diff options
author | rrs <rrs@FreeBSD.org> | 2015-01-14 12:46:58 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2015-01-14 12:46:58 +0000 |
commit | 8bf38c19340378b27480564610633c22767a038c (patch) | |
tree | 85da5545f7332c0a712cff50104bf9fb991e94b5 | |
parent | 0af471d1f4ce104a73bb238f6fcce8d3251b7ccc (diff) | |
download | FreeBSD-src-8bf38c19340378b27480564610633c22767a038c.zip FreeBSD-src-8bf38c19340378b27480564610633c22767a038c.tar.gz |
Update the hwpmc driver to have the new type HASWELL_XEON. Also
go back through HASWELL, IVY_BRIDGE, IVY_BRIDGE_XEON and SANDY_BRIDGE
to straighten out all the missing PMCs. We also add a new pmc tool
pmcstudy, this allows one to run the various formulas from
the documents "Using Intel Vtune Amplifier XE on XXX Generation platforms" for
IB/SB and Haswell. The tool also allows one to postulate your own
formulas with any of the various PMC's. At some point I will enahance
this to work with Brendan Gregg's flame-graphs so we can flamegraph
various PMC interactions. Note the manual page also needs some
work (lots of work) but gnn has committed to help me with that ;-)
Reviewed by: gnn
MFC after:1 month
Sponsored by: Netflix Inc.
-rw-r--r-- | lib/libpmc/libpmc.c | 25 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_core.c | 494 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_intel.c | 10 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_logging.c | 8 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_mod.c | 4 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_piv.c | 5 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_uncore.c | 4 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_x86.c | 4 | ||||
-rw-r--r-- | sys/dev/hwpmc/pmc_events.h | 343 | ||||
-rw-r--r-- | sys/sys/pmc.h | 1 | ||||
-rw-r--r-- | usr.sbin/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/eval_expr.c | 717 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/eval_expr.h | 58 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/pmcstudy.1 | 65 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/pmcstudy.c | 2425 |
16 files changed, 3911 insertions, 264 deletions
diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 5282bb2..2cdf6b7 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -200,6 +200,12 @@ static const struct pmc_event_descr haswell_event_table[] = __PMC_EV_ALIAS_HASWELL() }; +static const struct pmc_event_descr haswell_xeon_event_table[] = +{ + __PMC_EV_ALIAS_HASWELL_XEON() +}; + + static const struct pmc_event_descr ivybridge_event_table[] = { __PMC_EV_ALIAS_IVYBRIDGE() @@ -267,6 +273,7 @@ PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); PMC_MDEP_TABLE(nehalem_ex, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(haswell, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); +PMC_MDEP_TABLE(haswell_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); PMC_MDEP_TABLE(ivybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(ivybridge_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC); PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP); @@ -312,6 +319,7 @@ PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap); PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap); PMC_CLASS_TABLE_DESC(nehalem_ex, IAP, nehalem_ex, iap); PMC_CLASS_TABLE_DESC(haswell, IAP, haswell, iap); +PMC_CLASS_TABLE_DESC(haswell_xeon, IAP, haswell, iap); PMC_CLASS_TABLE_DESC(ivybridge, IAP, ivybridge, iap); PMC_CLASS_TABLE_DESC(ivybridge_xeon, IAP, ivybridge_xeon, iap); PMC_CLASS_TABLE_DESC(sandybridge, IAP, sandybridge, iap); @@ -626,6 +634,8 @@ static struct pmc_event_alias core2_aliases_without_iaf[] = { #define nehalem_ex_aliases_without_iaf core2_aliases_without_iaf #define haswell_aliases core2_aliases #define haswell_aliases_without_iaf core2_aliases_without_iaf +#define haswell_xeon_aliases core2_aliases +#define haswell_xeon_aliases_without_iaf core2_aliases_without_iaf #define ivybridge_aliases core2_aliases #define ivybridge_aliases_without_iaf core2_aliases_without_iaf #define ivybridge_xeon_aliases core2_aliases @@ -896,7 +906,8 @@ iap_allocate_pmc(enum pmc_event pe, char *ctrspec, n = pmc_parse_mask(iap_rsp_mask_sb_sbx_ib, p, &rsp); } else return (-1); - } else if (cpu_info.pm_cputype == PMC_CPU_INTEL_HASWELL) { + } else if (cpu_info.pm_cputype == PMC_CPU_INTEL_HASWELL || + cpu_info.pm_cputype == PMC_CPU_INTEL_HASWELL_XEON) { if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) { n = pmc_parse_mask(iap_rsp_mask_haswell, p, &rsp); } else @@ -2788,6 +2799,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = haswell_event_table; count = PMC_EVENT_TABLE_SIZE(haswell); break; + case PMC_CPU_INTEL_HASWELL_XEON: + ev = haswell_xeon_event_table; + count = PMC_EVENT_TABLE_SIZE(haswell_xeon); + break; case PMC_CPU_INTEL_IVYBRIDGE: ev = ivybridge_event_table; count = PMC_EVENT_TABLE_SIZE(ivybridge); @@ -3115,6 +3130,9 @@ pmc_init(void) pmc_class_table[n++] = &haswelluc_class_table_descr; PMC_MDEP_INIT_INTEL_V2(haswell); break; + case PMC_CPU_INTEL_HASWELL_XEON: + PMC_MDEP_INIT_INTEL_V2(haswell_xeon); + break; case PMC_CPU_INTEL_IVYBRIDGE: PMC_MDEP_INIT_INTEL_V2(ivybridge); break; @@ -3280,6 +3298,11 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) ev = haswell_event_table; evfence = haswell_event_table + PMC_EVENT_TABLE_SIZE(haswell); break; + case PMC_CPU_INTEL_HASWELL_XEON: + ev = haswell_xeon_event_table; + evfence = haswell_xeon_event_table + PMC_EVENT_TABLE_SIZE(haswell_xeon); + break; + case PMC_CPU_INTEL_IVYBRIDGE: ev = ivybridge_event_table; evfence = ivybridge_event_table + PMC_EVENT_TABLE_SIZE(ivybridge); diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index a2bcf73..7d27817 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -38,7 +38,11 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <machine/intr_machdep.h> +#if (__FreeBSD_version >= 1100000) #include <x86/apicvar.h> +#else +#include <machine/apicvar.h> +#endif #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/md_var.h> @@ -569,7 +573,8 @@ struct iap_event_descr { #define IAP_F_IBX (1 << 9) /* CPU: Ivy Bridge Xeon */ #define IAP_F_HW (1 << 10) /* CPU: Haswell */ #define IAP_F_CAS (1 << 11) /* CPU: Atom Silvermont */ -#define IAP_F_FM (1 << 12) /* Fixed mask */ +#define IAP_F_HWX (1 << 12) /* CPU: Haswell Xeon */ +#define IAP_F_FM (1 << 13) /* Fixed mask */ #define IAP_F_ALLCPUSCORE2 \ (IAP_F_CC | IAP_F_CC2 | IAP_F_CC2E | IAP_F_CA) @@ -613,11 +618,11 @@ static struct iap_event_descr iap_events[] = { IAP_F_SBX | IAP_F_CAS), IAPDESCR(03H_02H, 0x03, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | - IAP_F_CAS), + IAP_F_CAS | IAP_F_HWX), IAPDESCR(03H_04H, 0x03, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O | IAP_F_CAS), IAPDESCR(03H_08H, 0x03, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB | - IAP_F_SBX | IAP_F_CAS), + IAP_F_SBX | IAP_F_CAS | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB | IAP_F_SBX | IAP_F_CAS), IAPDESCR(03H_20H, 0x03, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_CAS), @@ -638,9 +643,9 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(05H_00H, 0x05, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(05H_02H, 0x05, 0x02, IAP_F_FM | IAP_F_I7O | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(05H_03H, 0x05, 0x03, IAP_F_FM | IAP_F_I7O | IAP_F_CAS), IAPDESCR(06H_00H, 0x06, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2 | @@ -654,7 +659,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(07H_00H, 0x07, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2), IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | - IAP_F_HW), + IAP_F_HW | IAP_F_HWX), IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(07H_06H, 0x07, 0x06, IAP_F_FM | IAP_F_CA), @@ -662,26 +667,27 @@ static struct iap_event_descr iap_events[] = { IAP_F_SBX), IAPDESCR(08H_01H, 0x08, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW), + IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(08H_02H, 0x08, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW), + IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(08H_04H, 0x08, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW), + IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(08H_05H, 0x08, 0x05, IAP_F_FM | IAP_F_CA), IAPDESCR(08H_06H, 0x08, 0x06, IAP_F_FM | IAP_F_CA), IAPDESCR(08H_07H, 0x08, 0x07, IAP_F_FM | IAP_F_CA), IAPDESCR(08H_08H, 0x08, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(08H_09H, 0x08, 0x09, IAP_F_FM | IAP_F_CA), - IAPDESCR(08H_0EH, 0x08, 0x0E, IAP_F_FM | IAP_F_HW), + IAPDESCR(08H_0EH, 0x08, 0x0E, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_SBX | IAP_F_HW), - IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW), - IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW), - IAPDESCR(08H_60H, 0x08, 0x60, IAP_F_FM | IAP_F_HW), - IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_HW), + IAP_F_SBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(08H_40H, 0x08, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW | IAP_F_HWX), + IAPDESCR(08H_60H, 0x08, 0x60, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(08H_80H, 0x08, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_HW | IAP_F_HWX), IAPDESCR(08H_81H, 0x08, 0x81, IAP_F_FM | IAP_F_IB | IAP_F_IBX), IAPDESCR(08H_82H, 0x08, 0x82, IAP_F_FM | IAP_F_IB | IAP_F_IBX), IAPDESCR(08H_84H, 0x08, 0x84, IAP_F_FM | IAP_F_IB | IAP_F_IBX), + IAPDESCR(08H_88H, 0x08, 0x88, IAP_F_IB | IAP_F_IBX), IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O), IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O), @@ -697,15 +703,16 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(0CH_02H, 0x0C, 0x02, IAP_F_FM | IAP_F_CC2), IAPDESCR(0CH_03H, 0x0C, 0x03, IAP_F_FM | IAP_F_CA), - IAPDESCR(0DH_03H, 0x0D, 0x03, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_HW), + IAPDESCR(0DH_03H, 0x0D, 0x03, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_HW | + IAP_F_IB | IAP_F_IBX | IAP_F_HWX), IAPDESCR(0DH_40H, 0x0D, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(0EH_02H, 0x0E, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(0EH_10H, 0x0E, 0x10, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(0EH_20H, 0x0E, 0x20, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(0EH_40H, 0x0E, 0x40, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), + IAPDESCR(0EH_10H, 0x0E, 0x10, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(0EH_20H, 0x0E, 0x20, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(0EH_40H, 0x0E, 0x40, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(0FH_01H, 0x0F, 0x01, IAP_F_FM | IAP_F_I7), IAPDESCR(0FH_02H, 0x0F, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -716,24 +723,24 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(10H_00H, 0x10, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(10H_01H, 0x10, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 | - IAP_F_WM | IAP_F_SB | IAP_F_SBX), + IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | IAP_F_IBX ), IAPDESCR(10H_02H, 0x10, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(10H_04H, 0x10, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(10H_08H, 0x10, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(10H_10H, 0x10, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_SBX), + IAP_F_SBX | IAP_F_IB | IAP_F_IBX), IAPDESCR(10H_20H, 0x10, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_SBX), + IAP_F_SBX | IAP_F_IB | IAP_F_IBX), IAPDESCR(10H_40H, 0x10, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_SBX), + IAP_F_SBX | IAP_F_IB | IAP_F_IBX), IAPDESCR(10H_80H, 0x10, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_SBX), + IAP_F_SBX | IAP_F_IB | IAP_F_IBX), IAPDESCR(10H_81H, 0x10, 0x81, IAP_F_FM | IAP_F_CA), IAPDESCR(11H_00H, 0x11, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2), IAPDESCR(11H_01H, 0x11, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_SB | - IAP_F_SBX), - IAPDESCR(11H_02H, 0x11, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_SBX), + IAP_F_SBX | IAP_F_IB | IAP_F_IBX), + IAPDESCR(11H_02H, 0x11, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | IAP_F_IBX), IAPDESCR(11H_81H, 0x11, 0x81, IAP_F_FM | IAP_F_CA), IAPDESCR(12H_00H, 0x12, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), @@ -796,30 +803,30 @@ static struct iap_event_descr iap_events[] = { IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(24H_20H, 0x24, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(24H_21H, 0x24, 0x21, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_22H, 0x24, 0x22, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_24H, 0x24, 0x24, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_27H, 0x24, 0x27, IAP_F_FM | IAP_F_HW), + IAPDESCR(24H_21H, 0x24, 0x21, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_22H, 0x24, 0x22, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_24H, 0x24, 0x24, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_27H, 0x24, 0x27, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(24H_41H, 0x24, 0x41, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_42H, 0x24, 0x42, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_44H, 0x24, 0x44, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_50H, 0x24, 0x50, IAP_F_FM | IAP_F_HW), + IAPDESCR(24H_41H, 0x24, 0x41, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_42H, 0x24, 0x42, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_44H, 0x24, 0x44, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_50H, 0x24, 0x50, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(24H_80H, 0x24, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(24H_E1H, 0x24, 0xE1, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_E2H, 0x24, 0xE2, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_E4H, 0x24, 0xE4, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_E7H, 0x24, 0xE7, IAP_F_FM | IAP_F_HW), + IAPDESCR(24H_E1H, 0x24, 0xE1, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_E2H, 0x24, 0xE2, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_E4H, 0x24, 0xE4, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_E7H, 0x24, 0xE7, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(24H_F8H, 0x24, 0xF8, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_3FH, 0x24, 0x3F, IAP_F_FM | IAP_F_HW), - IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW), + IAPDESCR(24H_F8H, 0x24, 0xF8, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_3FH, 0x24, 0x3F, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW | IAP_F_HWX), IAPDESCR(25H, 0x25, IAP_M_CORE, IAP_F_ALLCPUSCORE2), @@ -850,7 +857,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(27H_10H, 0x27, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(27H_20H, 0x27, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(27H_40H, 0x27, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(27H_50H, 0x27, 0x50, IAP_F_FM | IAP_F_HW), + IAPDESCR(27H_50H, 0x27, 0x50, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(27H_80H, 0x27, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(27H_E0H, 0x27, 0xE0, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(27H_F0H, 0x27, 0xF0, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -878,10 +885,10 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(2EH_02H, 0x2E, 0x02, IAP_F_FM | IAP_F_WM), IAPDESCR(2EH_41H, 0x2E, 0x41, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | - IAP_F_CAS), + IAP_F_CAS | IAP_F_HWX), IAPDESCR(2EH_4FH, 0x2E, 0x4F, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | - IAP_F_CAS), + IAP_F_CAS | IAP_F_HWX), IAPDESCR(30H, 0x30, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH, IAP_F_ALLCPUSCORE2), @@ -897,10 +904,10 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(3CH_00H, 0x3C, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | - IAP_F_HW | IAP_F_CAS), + IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(3CH_01H, 0x3C, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | - IAP_F_HW | IAP_F_CAS), + IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(3CH_02H, 0x3C, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(3DH_01H, 0x3D, 0x01, IAP_F_FM | IAP_F_I7O), @@ -942,25 +949,25 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(48H_00H, 0x48, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(48H_01H, 0x48, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(48H_02H, 0x48, 0x02, IAP_F_FM | IAP_F_I7O), IAPDESCR(49H_00H, 0x49, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(49H_01H, 0x49, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | - IAP_F_HW), + IAP_F_HW | IAP_F_HWX), IAPDESCR(49H_02H, 0x49, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | - IAP_F_HW), + IAP_F_HW | IAP_F_HWX), IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(49H_0EH, 0x49, 0x0E, IAP_F_FM | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(49H_0EH, 0x49, 0x0E, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_HW), - IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW), - IAPDESCR(49H_60H, 0x49, 0x60, IAP_F_FM | IAP_F_HW), - IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7 | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_HW | IAP_F_HWX), + IAPDESCR(49H_40H, 0x49, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW | IAP_F_HWX), + IAPDESCR(49H_60H, 0x49, 0x60, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(49H_80H, 0x49, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7 | IAP_F_HW | IAP_F_HWX), IAPDESCR(4BH_00H, 0x4B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(4BH_01H, 0x4B, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7O), @@ -970,9 +977,9 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(4CH_00H, 0x4C, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(4CH_01H, 0x4C, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(4CH_02H, 0x4C, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(4DH_01H, 0x4D, 0x01, IAP_F_FM | IAP_F_I7O), @@ -989,7 +996,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(4FH_10H, 0x4F, 0x10, IAP_F_FM | IAP_F_WM), IAPDESCR(51H_01H, 0x51, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(51H_02H, 0x51, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX), IAPDESCR(51H_04H, 0x51, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | @@ -1001,10 +1008,10 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(53H_01H, 0x53, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(58H_01H, 0x58, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(58H_02H, 0x58, 0x02, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(58H_04H, 0x58, 0x04, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(58H_08H, 0x58, 0x08, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), + IAPDESCR(58H_01H, 0x58, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(58H_02H, 0x58, 0x02, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(58H_04H, 0x58, 0x04, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(58H_08H, 0x58, 0x08, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(59H_20H, 0x59, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(59H_40H, 0x59, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_SBX), @@ -1016,25 +1023,25 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(5BH_4FH, 0x5B, 0x4F, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(5CH_01H, 0x5C, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(5CH_02H, 0x5C, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(5EH_01H, 0x5E, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), - IAPDESCR(5FH_01H, 0x5F, 0x01, IAP_F_FM | IAP_F_IB), - IAPDESCR(5FH_04H, 0x5F, 0x04, IAP_F_IBX), + IAPDESCR(5FH_01H, 0x5F, 0x01, IAP_F_FM | IAP_F_IB ), /* IB not in manual */ + IAPDESCR(5FH_04H, 0x5F, 0x04, IAP_F_IBX | IAP_F_IB), IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2), IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(61H, 0x61, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2), IAPDESCR(61H_00H, 0x61, 0x00, IAP_F_FM | IAP_F_CC), @@ -1046,9 +1053,9 @@ static struct iap_event_descr iap_events[] = { IAP_F_CA | IAP_F_CC2), IAPDESCR(63H, 0x63, IAP_M_CORE, IAP_F_CC), IAPDESCR(63H_01H, 0x63, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(63H_02H, 0x63, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(64H, 0x64, IAP_M_CORE, IAP_F_CA | IAP_F_CC2), IAPDESCR(64H_40H, 0x64, 0x40, IAP_F_FM | IAP_F_CC), @@ -1090,20 +1097,25 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(78H, 0x78, IAP_M_CORE | IAP_M_SNOOPTYPE, IAP_F_CA | IAP_F_CC2), IAPDESCR(79H_02H, 0x79, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(79H_04H, 0x79, 0x04, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(79H_08H, 0x79, 0x08, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(79H_10H, 0x79, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + + IAPDESCR(79H_18H, 0x79, 0x18, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(79H_20H, 0x79, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + + IAPDESCR(79H_24H, 0x79, 0x24, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(79H_30H, 0x79, 0x30, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(79H_18H, 0x79, 0x18, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(79H_24H, 0x79, 0x24, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(79H_3CH, 0x79, 0x3C, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + + IAPDESCR(79H_3CH, 0x79, 0x3C, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(7AH, 0x7A, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2), @@ -1120,10 +1132,10 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(80H_01H, 0x80, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_CAS), IAPDESCR(80H_02H, 0x80, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | - IAP_F_CAS), + IAP_F_CAS | IAP_F_HWX), IAPDESCR(80H_03H, 0x80, 0x03, IAP_F_FM | IAP_F_CA | IAP_F_I7 | IAP_F_WM | IAP_F_CAS), - IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM), + IAPDESCR(80H_04H, 0x80, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_IB | IAP_F_IBX), IAPDESCR(81H_00H, 0x81, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(81H_01H, 0x81, 0x01, IAP_F_FM | IAP_F_I7O), @@ -1141,74 +1153,74 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(85H_00H, 0x85, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(85H_01H, 0x85, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(85H_02H, 0x85, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(85H_04H, 0x85, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(85H_0EH, 0x85, 0x0E, IAP_F_FM | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(85H_0EH, 0x85, 0x0E, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(85H_10H, 0x85, 0x10, IAP_F_FM | IAP_F_I7O | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7O | IAP_F_HW), - IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW), - IAPDESCR(85H_60H, 0x85, 0x60, IAP_F_FM | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(85H_20H, 0x85, 0x20, IAP_F_FM | IAP_F_I7O | IAP_F_HW | IAP_F_HWX), + IAPDESCR(85H_40H, 0x85, 0x40, IAP_F_FM | IAP_F_I7O | IAP_F_HW | IAP_F_HWX), + IAPDESCR(85H_60H, 0x85, 0x60, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(85H_80H, 0x85, 0x80, IAP_F_FM | IAP_F_WM | IAP_F_I7O), IAPDESCR(86H_00H, 0x86, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(87H_00H, 0x87, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(87H_01H, 0x87, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(87H_02H, 0x87, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(87H_04H, 0x87, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(87H_08H, 0x87, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(87H_0FH, 0x87, 0x0F, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(88H_00H, 0x88, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(88H_01H, 0x88, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_02H, 0x88, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_04H, 0x88, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_07H, 0x88, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(88H_08H, 0x88, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_10H, 0x88, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_20H, 0x88, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_30H, 0x88, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(88H_40H, 0x88, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_7FH, 0x88, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(88H_80H, 0x88, 0x80, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(88H_FFH, 0x88, 0xFF, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_00H, 0x89, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(89H_01H, 0x89, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_02H, 0x89, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(89H_04H, 0x89, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_07H, 0x89, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(89H_08H, 0x89, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_10H, 0x89, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_20H, 0x89, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_30H, 0x89, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(89H_40H, 0x89, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(89H_80H, 0x89, 0x80, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(89H_FFH, 0x89, 0xFF, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(8AH_00H, 0x8A, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(8BH_00H, 0x8B, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), @@ -1223,45 +1235,45 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(93H_00H, 0x93, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(94H_00H, 0x94, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), - IAPDESCR(9CH_01H, 0x9C, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(97H_00H, 0x97, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(98H_00H, 0x98, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2), + + IAPDESCR(9CH_01H, 0x9C, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A0H_00H, 0xA0, 0x00, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(A1H_01H, 0xA1, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A1H_02H, 0xA1, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A1H_04H, 0xA1, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A1H_08H, 0xA1, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A1H_0CH, 0xA1, 0x0C, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX), - IAPDESCR(A1H_10H, 0xA1, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A1H_04H, 0xA1, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | /* No desc in IB for this*/ + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A1H_08H, 0xA1, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | /* No desc in IB for this*/ + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A1H_0CH, 0xA1, 0x0C, IAP_F_IB | IAP_F_IBX), + IAPDESCR(A1H_10H, 0xA1, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | /* No desc in IB for this*/ + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A1H_20H, 0xA1, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | /* No desc in IB for this*/ + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A1H_30H, 0xA1, 0x30, IAP_F_FM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(A1H_40H, 0xA1, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A1H_80H, 0xA1, 0x80, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A2H_00H, 0xA2, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(A2H_01H, 0xA2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A2H_02H, 0xA2, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX), IAPDESCR(A2H_04H, 0xA2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A2H_08H, 0xA2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A2H_10H, 0xA2, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(A2H_20H, 0xA2, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX), IAPDESCR(A2H_40H, 0xA2, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | @@ -1269,15 +1281,17 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(A3H_01H, 0xA3, 0x01, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A3H_02H, 0xA3, 0x02, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(A3H_04H, 0xA3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(A3H_05H, 0xA3, 0x05, IAP_F_FM | IAP_F_HW), - IAPDESCR(A3H_08H, 0xA3, 0x08, IAP_F_FM | IAP_F_IBX | IAP_F_HW), + IAPDESCR(A3H_01H, 0xA3, 0x01, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A3H_02H, 0xA3, 0x02, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A3H_04H, 0xA3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB), + IAPDESCR(A3H_05H, 0xA3, 0x05, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(A3H_08H, 0xA3, 0x08, IAP_F_FM | IAP_F_IBX | IAP_F_HW | IAP_F_IB | IAP_F_HWX), + IAPDESCR(A3H_0CH, 0xA3, 0x08, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM), + IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_IBX | + IAP_F_IB |IAP_F_SB | IAP_F_SBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(AAH_01H, 0xAA, 0x01, IAP_F_FM | IAP_F_CC2), IAPDESCR(AAH_02H, 0xAA, 0x02, IAP_F_FM | IAP_F_CA), @@ -1295,17 +1309,17 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(ACH_0AH, 0xAC, 0x0A, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(AEH_01H, 0xAE, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B0H_00H, 0xB0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(B0H_01H, 0xB0, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B0H_10H, 0xB0, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7O), IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7O), IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -1315,7 +1329,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(B1H_01H, 0xB1, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(B1H_02H, 0xB1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(B1H_04H, 0xB1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B1H_08H, 0xB1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B1H_10H, 0xB1, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -1353,7 +1367,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(B6H_04H, 0xB6, 0x04, IAP_F_CAS), IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_CAS), IAPDESCR(B7H_02H, 0xB7, 0x02, IAP_F_CAS), IAPDESCR(B8H_01H, 0xB8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM), @@ -1364,30 +1378,30 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(BAH_02H, 0xBA, 0x02, IAP_F_FM | IAP_F_I7O), IAPDESCR(BBH_01H, 0xBB, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), - IAPDESCR(BCH_11H, 0xBC, 0x11, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_12H, 0xBC, 0x12, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_14H, 0xBC, 0x14, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_18H, 0xBC, 0x18, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_21H, 0xBC, 0x21, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_22H, 0xBC, 0x22, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_24H, 0xBC, 0x24, IAP_F_FM | IAP_F_HW), - IAPDESCR(BCH_28H, 0xBC, 0x28, IAP_F_FM | IAP_F_HW), + IAPDESCR(BCH_11H, 0xBC, 0x11, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_12H, 0xBC, 0x12, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_14H, 0xBC, 0x14, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_18H, 0xBC, 0x18, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_21H, 0xBC, 0x21, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_22H, 0xBC, 0x22, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_24H, 0xBC, 0x24, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(BCH_28H, 0xBC, 0x28, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(BDH_01H, 0xBD, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(BDH_20H, 0xBD, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(BFH_05H, 0xBF, 0x05, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | - IAP_F_CAS), + IAP_F_CAS | IAP_F_HWX), IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB), IAPDESCR(C0H_04H, 0xC0, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | @@ -1398,21 +1412,22 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(C1H_01H, 0xC1, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(C1H_02H, 0xC1, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(C1H_08H, 0xC1, 0x08, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C1H_10H, 0xC1, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C1H_20H, 0xC1, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(C1H_40H, 0xC1, 0x40, IAP_F_FM | IAP_F_HW), + IAPDESCR(C1H_40H, 0xC1, 0x40, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(C1H_80H, 0xC1, 0x80, IAP_F_IB | IAP_F_IBX), IAPDESCR(C1H_FEH, 0xC1, 0xFE, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(C2H_00H, 0xC2, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(C2H_01H, 0xC2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(C2H_02H, 0xC2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C2H_04H, 0xC2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM), IAPDESCR(C2H_07H, 0xC2, 0x07, IAP_F_FM | IAP_F_CA | IAP_F_CC2), @@ -1424,37 +1439,39 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(C3H_01H, 0xC3, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_CAS), IAPDESCR(C3H_02H, 0xC3, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | + IAP_F_CAS | IAP_F_HWX), IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(C3H_08H, 0xC3, 0x08, IAP_F_CAS), IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7O), IAPDESCR(C3H_20H, 0xC3, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_00H, 0xC4, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(C4H_01H, 0xC4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_02H, 0xC4, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_04H, 0xC4, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_08H, 0xC4, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), IAPDESCR(C4H_0CH, 0xC4, 0x0C, IAP_F_FM | IAP_F_CA | IAP_F_CC2), IAPDESCR(C4H_0FH, 0xC4, 0x0F, IAP_F_FM | IAP_F_CA), IAPDESCR(C4H_10H, 0xC4, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_20H, 0xC4, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_40H, 0xC4, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C4H_7EH, 0xC4, 0x7E, IAP_F_CAS), IAPDESCR(C4H_BFH, 0xC4, 0xBF, IAP_F_CAS), IAPDESCR(C4H_EBH, 0xC4, 0xEB, IAP_F_CAS), @@ -1466,17 +1483,17 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(C5H_01H, 0xC5, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C5H_02H, 0xC5, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(C5H_04H, 0xC5, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C5H_10H, 0xC5, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(C5H_20H, 0xC5, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(C5H_7EH, 0xC5, 0x7E, IAP_F_CAS), IAPDESCR(C5H_BFH, 0xC5, 0xBF, IAP_F_CAS), IAPDESCR(C5H_EBH, 0xC5, 0xEB, IAP_F_CAS), @@ -1511,15 +1528,15 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(CAH_00H, 0xCA, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(CAH_01H, 0xCA, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_CAS), IAPDESCR(CAH_02H, 0xCA, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CAH_04H, 0xCA, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CAH_08H, 0xCA, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CAH_10H, 0xCA, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CAH_1EH, 0xCA, 0x1E, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CAH_20H, 0xCA, 0x20, IAP_F_CAS), IAPDESCR(CAH_3FH, 0xCA, 0x3F, IAP_F_CAS), IAPDESCR(CAH_50H, 0xCA, 0x50, IAP_F_CAS), @@ -1545,11 +1562,11 @@ static struct iap_event_descr iap_events[] = { IAP_F_I7 | IAP_F_WM), IAPDESCR(CCH_03H, 0xCC, 0x03, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(CCH_20H, 0xCC, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(CDH_00H, 0xCD, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(CDH_01H, 0xCD, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX), IAPDESCR(CDH_02H, 0xCD, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), @@ -1559,55 +1576,67 @@ static struct iap_event_descr iap_events[] = { /* Sandy Bridge / Sandy Bridge Xeon - 11, 12, 21, 41, 42, 81, 82 */ IAPDESCR(D0H_00H, 0xD0, 0x00, IAP_F_FM | IAP_F_CC), IAPDESCR(D0H_01H, 0xD0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), - IAPDESCR(D0H_02H, 0xD0, 0x02, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(D0H_10H, 0xD0, 0x10, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(D0H_02H, 0xD0, 0x02, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), + IAPDESCR(D0H_10H, 0xD0, 0x10, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), IAPDESCR(D0H_11H, 0xD0, 0x11, IAP_F_FM | IAP_F_SB | IAP_F_SBX), IAPDESCR(D0H_12H, 0xD0, 0x12, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(D0H_20H, 0xD0, 0x20, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), + IAPDESCR(D0H_20H, 0xD0, 0x20, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), IAPDESCR(D0H_21H, 0xD0, 0x21, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(D0H_40H, 0xD0, 0x40, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(D0H_41H, 0xD0, 0x41, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(D0H_42H, 0xD0, 0x42, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(D0H_80H, 0xD0, 0x80, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW), - IAPDESCR(D0H_81H, 0xD0, 0x81, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - IAPDESCR(D0H_82H, 0xD0, 0x82, IAP_F_FM | IAP_F_SB | IAP_F_SBX), - + IAPDESCR(D0H_40H, 0xD0, 0x40, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), + IAPDESCR(D0H_41H, 0xD0, 0x41, IAP_F_FM | IAP_F_SB | IAP_F_SBX | + IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), /* Not in spec but in linux and Vtune guide */ + IAPDESCR(D0H_42H, 0xD0, 0x42, IAP_F_FM | IAP_F_SB | IAP_F_SBX | + IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), /* Not in spec but in linux and Vtune guide */ + IAPDESCR(D0H_80H, 0xD0, 0x80, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | + IAP_F_HWX), + IAPDESCR(D0H_81H, 0xD0, 0x81, IAP_F_FM | IAP_F_SB | IAP_F_SBX | + IAP_F_IB | IAP_F_IBX), /* Not in spec but in linux and Vtune guide */ + IAPDESCR(D0H_82H, 0xD0, 0x82, IAP_F_FM | IAP_F_SB | IAP_F_SBX | + IAP_F_IB | IAP_F_IBX), /* Not in spec but in linux and Vtune guide */ IAPDESCR(D1H_01H, 0xD1, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_SB | - IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D1H_02H, 0xD1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D1H_04H, 0xD1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), - IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM), - IAPDESCR(D1H_10H, 0xD1, 0x10, IAP_F_HW), - IAPDESCR(D1H_20H, 0xD1, 0x20, IAP_F_FM | IAP_F_SBX | IAP_F_IBX), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(D1H_08H, 0xD1, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_IB | + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(D1H_10H, 0xD1, 0x10, IAP_F_HW | IAP_F_IB | IAP_F_IBX | IAP_F_HWX), + IAPDESCR(D1H_20H, 0xD1, 0x20, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | + IAP_F_HW | IAP_F_HWX), IAPDESCR(D1H_40H, 0xD1, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_01H, 0xD2, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_02H, 0xD2, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_04H, 0xD2, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_08H, 0xD2, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_0FH, 0xD2, 0x0F, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_SBX | IAP_F_IB | - IAP_F_IBX | IAP_F_HW), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(D2H_10H, 0xD2, 0x10, IAP_F_FM | IAP_F_CC2E), IAPDESCR(D3H_01H, 0xD3, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_SBX | - IAP_F_IBX | IAP_F_HW), - IAPDESCR(D3H_04H, 0xD3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(D3H_10H, 0xD3, 0x10, IAP_F_IBX), - IAPDESCR(D3H_20H, 0xD3, 0x20, IAP_F_IBX), + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), + IAPDESCR(D3H_03H, 0xD0, 0x3, IAP_F_IBX ), + IAPDESCR(D3H_04H, 0xD3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX), /* Not defined for IBX */ + IAPDESCR(D3H_0CH, 0xD0, 0x0, IAP_F_IBX ), + IAPDESCR(D3H_10H, 0xD3, 0x10, IAP_F_IBX ), + IAPDESCR(D3H_20H, 0xD3, 0x20, IAP_F_IBX ), IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7 | IAP_F_WM), @@ -1668,7 +1697,8 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(E6H_08H, 0xE6, 0x08, IAP_F_CAS), IAPDESCR(E6H_10H, 0xE6, 0x10, IAP_F_CAS), - IAPDESCR(E6H_1FH, 0xE6, 0x1F, IAP_F_FM | IAP_F_IBX | IAP_F_HW), + IAPDESCR(E6H_1FH, 0xE6, 0x1F, IAP_F_FM | IAP_F_IB | + IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(E7H_01H, 0xE7, 0x01, IAP_F_CAS), @@ -1680,30 +1710,30 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(F0H_00H, 0xF0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(F0H_01H, 0xF0, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_02H, 0xF0, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_04H, 0xF0, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_08H, 0xF0, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_10H, 0xF0, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_20H, 0xF0, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_40H, 0xF0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F0H_80H, 0xF0, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F1H_01H, 0xF1, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB | - IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F1H_02H, 0xF1, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F1H_04H, 0xF1, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F1H_07H, 0xF1, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM | - IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW), + IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX), IAPDESCR(F2H_01H, 0xF2, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), @@ -1711,8 +1741,8 @@ static struct iap_event_descr iap_events[] = { IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(F2H_04H, 0xF2, 0x04, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), - IAPDESCR(F2H_05H, 0xF2, 0x05, IAP_F_FM | IAP_F_HW), - IAPDESCR(F2H_06H, 0xF2, 0x06, IAP_F_FM | IAP_F_HW), + IAPDESCR(F2H_05H, 0xF2, 0x05, IAP_F_FM | IAP_F_HW | IAP_F_HWX), + IAPDESCR(F2H_06H, 0xF2, 0x06, IAP_F_FM | IAP_F_HW | IAP_F_HWX), IAPDESCR(F2H_08H, 0xF2, 0x08, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX), IAPDESCR(F2H_0AH, 0xF2, 0x0A, IAP_F_FM | IAP_F_SB | IAP_F_SBX | @@ -2030,6 +2060,7 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm, case PMC_CPU_INTEL_IVYBRIDGE: case PMC_CPU_INTEL_IVYBRIDGE_XEON: case PMC_CPU_INTEL_HASWELL: + case PMC_CPU_INTEL_HASWELL_XEON: if (iap_event_sb_sbx_ib_ibx_ok_on_counter(ev, ri) == 0) return (EINVAL); break; @@ -2071,6 +2102,9 @@ iap_allocate_pmc(int cpu, int ri, struct pmc *pm, case PMC_CPU_INTEL_HASWELL: cpuflag = IAP_F_HW; break; + case PMC_CPU_INTEL_HASWELL_XEON: + cpuflag = IAP_F_HWX; + break; case PMC_CPU_INTEL_IVYBRIDGE: cpuflag = IAP_F_IB; break; diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c index 6cf37b0..05880c9 100644 --- a/sys/dev/hwpmc/hwpmc_intel.c +++ b/sys/dev/hwpmc/hwpmc_intel.c @@ -179,8 +179,14 @@ pmc_intel_initialize(void) cputype = PMC_CPU_INTEL_IVYBRIDGE_XEON; nclasses = 3; break; + case 0x3F: /* Per Intel document 325462-045US 09/2014. */ + case 0x46: /* Per Intel document 325462-045US 09/2014. */ + /* Should 46 be XEON. probably its own? */ + cputype = PMC_CPU_INTEL_HASWELL_XEON; + nclasses = 3; + break; case 0x3C: /* Per Intel document 325462-045US 01/2013. */ - case 0x45: + case 0x45: /* Per Intel document 325462-045US 09/2014. */ cputype = PMC_CPU_INTEL_HASWELL; nclasses = 5; break; @@ -233,6 +239,7 @@ pmc_intel_initialize(void) case PMC_CPU_INTEL_SANDYBRIDGE_XEON: case PMC_CPU_INTEL_IVYBRIDGE_XEON: case PMC_CPU_INTEL_HASWELL: + case PMC_CPU_INTEL_HASWELL_XEON: error = pmc_core_initialize(pmc_mdep, ncpus, verov); break; @@ -318,6 +325,7 @@ pmc_intel_finalize(struct pmc_mdep *md) case PMC_CPU_INTEL_COREI7: case PMC_CPU_INTEL_NEHALEM_EX: case PMC_CPU_INTEL_HASWELL: + case PMC_CPU_INTEL_HASWELL_XEON: case PMC_CPU_INTEL_IVYBRIDGE: case PMC_CPU_INTEL_SANDYBRIDGE: case PMC_CPU_INTEL_WESTMERE: diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index ee5b897..9484fae 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#if (__FreeBSD_version >= 1100000) #include <sys/capsicum.h> +#endif #include <sys/file.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -568,8 +570,9 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) { int error; struct proc *p; +#if (__FreeBSD_version >= 1100000) cap_rights_t rights; - +#endif /* * As long as it is possible to get a LOR between pmc_sx lock and * proctree/allproc sx locks used for adding a new process, assure @@ -592,11 +595,12 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) po->po_file)); /* get a reference to the file state */ +#if (__FreeBSD_version >= 1100000) error = fget_write(curthread, logfd, cap_rights_init(&rights, CAP_WRITE), &po->po_file); if (error) goto error; - +#endif /* mark process as owning a log file */ po->po_flags |= PMC_PO_OWNS_LOGFILE; error = kproc_create(pmclog_loop, po, &po->po_kthread, diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index f1506d6..cb8ed37 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -320,8 +320,12 @@ static struct syscall_module_data pmc_syscall_mod = { NULL, &pmc_syscall_num, &pmc_sysent, +#if (__FreeBSD_version >= 1100000) { 0, NULL }, SY_THR_STATIC_KLD, +#else + { 0, NULL } +#endif }; static moduledata_t pmc_mod = { diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c index 0cd65b6..ff47cb8 100644 --- a/sys/dev/hwpmc/hwpmc_piv.c +++ b/sys/dev/hwpmc/hwpmc_piv.c @@ -39,9 +39,12 @@ __FBSDID("$FreeBSD$"); #include <sys/pmckern.h> #include <sys/smp.h> #include <sys/systm.h> - #include <machine/intr_machdep.h> +#if (__FreeBSD_version >= 1100000) #include <x86/apicvar.h> +#else +#include <machine/apicvar.h> +#endif #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/cputypes.h> diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c index 7e991dc..6a30eb0 100644 --- a/sys/dev/hwpmc/hwpmc_uncore.c +++ b/sys/dev/hwpmc/hwpmc_uncore.c @@ -38,7 +38,11 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <machine/intr_machdep.h> +#if (__FreeBSD_version >= 1100000) #include <x86/apicvar.h> +#else +#include <machine/apicvar.h> +#endif #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index 5c1194e..f571e41 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -40,7 +40,11 @@ __FBSDID("$FreeBSD$"); #include <machine/cpu.h> #include <machine/cputypes.h> #include <machine/intr_machdep.h> +#if (__FreeBSD_version >= 1100000) #include <x86/apicvar.h> +#else +#include <machine/apicvar.h> +#endif #include <machine/pmc_mdep.h> #include <machine/md_var.h> diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 8e82d6c..567d6f4 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -529,6 +529,7 @@ __PMC_EV(IAP, EVENT_08H_80H) \ __PMC_EV(IAP, EVENT_08H_81H) \ __PMC_EV(IAP, EVENT_08H_82H) \ __PMC_EV(IAP, EVENT_08H_84H) \ +__PMC_EV(IAP, EVENT_08H_88H) \ __PMC_EV(IAP, EVENT_09H_01H) \ __PMC_EV(IAP, EVENT_09H_02H) \ __PMC_EV(IAP, EVENT_09H_04H) \ @@ -910,6 +911,7 @@ __PMC_EV(IAP, EVENT_A3H_02H) \ __PMC_EV(IAP, EVENT_A3H_04H) \ __PMC_EV(IAP, EVENT_A3H_05H) \ __PMC_EV(IAP, EVENT_A3H_08H) \ +__PMC_EV(IAP, EVENT_A3H_0CH) \ __PMC_EV(IAP, EVENT_A6H_01H) \ __PMC_EV(IAP, EVENT_A7H_01H) \ __PMC_EV(IAP, EVENT_A8H_01H) \ @@ -992,6 +994,7 @@ __PMC_EV(IAP, EVENT_C1H_08H) \ __PMC_EV(IAP, EVENT_C1H_10H) \ __PMC_EV(IAP, EVENT_C1H_20H) \ __PMC_EV(IAP, EVENT_C1H_40H) \ +__PMC_EV(IAP, EVENT_C1H_80H) \ __PMC_EV(IAP, EVENT_C1H_FEH) \ __PMC_EV(IAP, EVENT_C2H_00H) \ __PMC_EV(IAP, EVENT_C2H_01H) \ @@ -1109,7 +1112,9 @@ __PMC_EV(IAP, EVENT_D2H_08H) \ __PMC_EV(IAP, EVENT_D2H_0FH) \ __PMC_EV(IAP, EVENT_D2H_10H) \ __PMC_EV(IAP, EVENT_D3H_01H) \ +__PMC_EV(IAP, EVENT_D3H_03H) \ __PMC_EV(IAP, EVENT_D3H_04H) \ +__PMC_EV(IAP, EVENT_D3H_0CH) \ __PMC_EV(IAP, EVENT_D3H_10H) \ __PMC_EV(IAP, EVENT_D3H_20H) \ __PMC_EV(IAP, EVENT_D4H_01H) \ @@ -2572,16 +2577,245 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H) /* * Aliases for Haswell core PMC events */ +#define __PMC_EV_ALIAS_HASWELL_XEON() \ +__PMC_EV_ALIAS("LD_BLOCKS.STORE_FORWARD", IAP_EVENT_03H_02H) \ +__PMC_EV_ALIAS("LD_BLOCKS.NO_SR", IAP_EVENT_03H_08H) \ +__PMC_EV_ALIAS("MISALIGN_MEM_REF.LOADS", IAP_EVENT_05H_01H) \ +__PMC_EV_ALIAS("MISALIGN_MEM_REF.STORES", IAP_EVENT_05H_02H) \ +__PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", IAP_EVENT_07H_01H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_08H_01H)\ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED_4K", IAP_EVENT_08H_02H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4K", \ + IAP_EVENT_08H_04H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_0EH) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_DURATION", IAP_EVENT_08H_10H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT_4K", IAP_EVENT_08H_20H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT_2M", IAP_EVENT_08H_40H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_08H_60H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.PDE_CACHE_MISS", IAP_EVENT_08H_80H) \ +__PMC_EV_ALIAS("INT_MISC.RECOVERY_CYCLES", IAP_EVENT_0DH_03H) \ +__PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \ +__PMC_EV_ALIAS("UOPS_ISSUED.FLAGS_MERGE", IAP_EVENT_0EH_10H) \ +__PMC_EV_ALIAS("UOPS_ISSUED.SLOW_LEA", IAP_EVENT_0EH_20H) \ +__PMC_EV_ALIAS("UOPS_ISSUED.SINGLE_MUL", IAP_EVENT_0EH_40H) \ +__PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_MISS", IAP_EVENT_24H_21H) \ +__PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_HIT", IAP_EVENT_24H_41H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_E1H) \ +__PMC_EV_ALIAS("L2_RQSTS.RFO_HIT", IAP_EVENT_24H_42H) \ +__PMC_EV_ALIAS("L2_RQSTS.RFO_MISS", IAP_EVENT_24H_22H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_RFO", IAP_EVENT_24H_E2H) \ +__PMC_EV_ALIAS("L2_RQSTS.CODE_RD_HIT", IAP_EVENT_24H_44H) \ +__PMC_EV_ALIAS("L2_RQSTS.CODE_RD_MISS", IAP_EVENT_24H_24H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_MISS", IAP_EVENT_24H_27H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_REFERENCES", IAP_EVENT_24H_E7H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_CODE_RD", IAP_EVENT_24H_E4H) \ +__PMC_EV_ALIAS("L2_RQSTS.L2_PF_HIT", IAP_EVENT_24H_50H) \ +__PMC_EV_ALIAS("L2_RQSTS.L2_PF_MISS", IAP_EVENT_24H_30H) \ +__PMC_EV_ALIAS("L2_RQSTS.ALL_PF", IAP_EVENT_24H_F8H) \ +__PMC_EV_ALIAS("L2_RQSTS.MISS", IAP_EVENT_24H_3FH) \ +__PMC_EV_ALIAS("L2_RQSTS.REFERENCES", IAP_EVENT_24H_FFH) \ +__PMC_EV_ALIAS("L2_DEMAND_RQSTS.WB_HIT", IAP_EVENT_27H_50H) \ +__PMC_EV_ALIAS("LONGEST_LAT_CACHE.REFERENCE", IAP_EVENT_2EH_4FH) \ +__PMC_EV_ALIAS("LONGEST_LAT_CACHE.MISS", IAP_EVENT_2EH_41H) \ +__PMC_EV_ALIAS("CPU_CLK_UNHALTED.THREAD_P", IAP_EVENT_3CH_00H) \ +__PMC_EV_ALIAS("CPU_CLK_THREAD_UNHALTED.REF_XCLK", IAP_EVENT_3CH_01H) \ +__PMC_EV_ALIAS("L1D_PEND_MISS.PENDING", IAP_EVENT_48H_01H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", \ + IAP_EVENT_49H_01H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_COMPLETED_4K", \ + IAP_EVENT_49H_02H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", \ + IAP_EVENT_49H_04H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_COMPLETED", IAP_EVENT_49H_0EH) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.WALK_DURATION", IAP_EVENT_49H_10H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.STLB_HIT_4K", IAP_EVENT_49H_20H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.STLB_HIT_2M", IAP_EVENT_49H_40H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.STLB_HIT", IAP_EVENT_49H_60H) \ +__PMC_EV_ALIAS("DTLB_STORE_MISSES.PDE_CACHE_MISS", IAP_EVENT_49H_80H) \ +__PMC_EV_ALIAS("LOAD_HIT_PRE.SW_PF", IAP_EVENT_4CH_01H) \ +__PMC_EV_ALIAS("LOAD_HIT_PRE.HW_PF", IAP_EVENT_4CH_02H) \ +__PMC_EV_ALIAS("L1D.REPLACEMENT", IAP_EVENT_51H_01H) \ +__PMC_EV_ALIAS("MOVE_ELIMINATION.INT_NOT_ELIMINATED", \ + IAP_EVENT_58H_04H) \ +__PMC_EV_ALIAS("MOVE_ELIMINATION.SMID_NOT_ELIMINATED", \ + IAP_EVENT_58H_08H) \ +__PMC_EV_ALIAS("MOVE_ELIMINATION.INT_ELIMINATED", IAP_EVENT_58H_01H) \ +__PMC_EV_ALIAS("MOVE_ELIMINATION.SMID_ELIMINATED", IAP_EVENT_58H_02H) \ +__PMC_EV_ALIAS("CPL_CYCLES.RING0", IAP_EVENT_5CH_02H) \ +__PMC_EV_ALIAS("CPL_CYCLES.RING123", IAP_EVENT_5CH_01H) \ +__PMC_EV_ALIAS("RS_EVENTS.EMPTY_CYCLES", IAP_EVENT_5EH_01H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", \ + IAP_EVENT_60H_01H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CORE_RD", \ + IAP_EVENT_60H_02H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", \ + IAP_EVENT_60H_04H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", \ + IAP_EVENT_60H_08H) \ +__PMC_EV_ALIAS("LOCK_CYCLES.SPLIT_LOCK_UC_LOCK_DURATION", \ + IAP_EVENT_63H_01H) \ +__PMC_EV_ALIAS("LOCK_CYCLES.CACHE_LOCK_DURATION", IAP_EVENT_63H_02H) \ +__PMC_EV_ALIAS("IDQ.EMPTY", IAP_EVENT_79H_02H) \ +__PMC_EV_ALIAS("IDQ.MITE_UOPS", IAP_EVENT_79H_04H) \ +__PMC_EV_ALIAS("IDQ.DSB_UOPS", IAP_EVENT_79H_08H) \ +__PMC_EV_ALIAS("IDQ.MS_DSB_UOPS", IAP_EVENT_79H_10H) \ +__PMC_EV_ALIAS("IDQ.MS_MITE_UOPS", IAP_EVENT_79H_20H) \ +__PMC_EV_ALIAS("IDQ.MS_UOPS", IAP_EVENT_79H_30H) \ +__PMC_EV_ALIAS("IDQ.ALL_DSB_CYCLES_ANY_UOPS", IAP_EVENT_79H_18H) \ +__PMC_EV_ALIAS("IDQ.ALL_DSB_CYCLES_4_UOPS", IAP_EVENT_79H_18H) \ +__PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_ANY_UOPS", IAP_EVENT_79H_24H) \ +__PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_4_UOPS", IAP_EVENT_79H_24H) \ +__PMC_EV_ALIAS("IDQ.MITE_ALL_UOPS", IAP_EVENT_79H_3CH) \ +__PMC_EV_ALIAS("ICACHE.MISSES", IAP_EVENT_80H_02H) \ +__PMC_EV_ALIAS("ITLB_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_85H_01H) \ +__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED_4K", IAP_EVENT_85H_02H) \ +__PMC_EV_ALIAS("TLB_MISSES.WALK_COMPLETED_2M_4M", IAP_EVENT_85H_04H) \ +__PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_0EH) \ +__PMC_EV_ALIAS("ITLB_MISSES.WALK_DURATION", IAP_EVENT_85H_10H) \ +__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT_4K", IAP_EVENT_85H_20H) \ +__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT_2M", IAP_EVENT_85H_40H) \ +__PMC_EV_ALIAS("ITLB_MISSES.STLB_HIT", IAP_EVENT_85H_60H) \ +__PMC_EV_ALIAS("ILD_STALL.LCP", IAP_EVENT_87H_01H) \ +__PMC_EV_ALIAS("ILD_STALL.IQ_FULL", IAP_EVENT_87H_04H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.COND", IAP_EVENT_88H_01H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_JMP", IAP_EVENT_88H_02H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_JMP_NON_CALL_RET", \ + IAP_EVENT_88H_04H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.RETURN_NEAR", IAP_EVENT_88H_08H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_88H_10H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_88H_20H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.NONTAKEN", IAP_EVENT_88H_40H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.TAKEN", IAP_EVENT_88H_80H) \ +__PMC_EV_ALIAS("BR_INST_EXEC.ALL_BRANCHES", IAP_EVENT_88H_FFH) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.COND", IAP_EVENT_89H_01H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_JMP_NON_CALL_RET", \ + IAP_EVENT_89H_04H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.RETURN_NEAR", IAP_EVENT_89H_08H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.DIRECT_NEAR_CALL", IAP_EVENT_89H_10H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.INDIRECT_NEAR_CALL", IAP_EVENT_89H_20H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.NONTAKEN", IAP_EVENT_89H_40H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.TAKEN", IAP_EVENT_89H_80H) \ +__PMC_EV_ALIAS("BR_MISP_EXEC.ALL_BRANCHES", IAP_EVENT_89H_FFH) \ +__PMC_EV_ALIAS("IDQ_UOPS_NOT_DELIVERED.CORE", IAP_EVENT_9CH_01H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_0", IAP_EVENT_A1H_01H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_1", IAP_EVENT_A1H_02H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_2", IAP_EVENT_A1H_04H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_3", IAP_EVENT_A1H_08H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_4", IAP_EVENT_A1H_10H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_5", IAP_EVENT_A1H_20H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_6", IAP_EVENT_A1H_40H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED_PORT.PORT_7", IAP_EVENT_A1H_80H) \ +__PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \ +__PMC_EV_ALIAS("RESOURCE_STALLS.RS", IAP_EVENT_A2H_04H) \ +__PMC_EV_ALIAS("RESOURCE_STALLS.SB", IAP_EVENT_A2H_08H) \ +__PMC_EV_ALIAS("RESOURCE_STALLS.ROB", IAP_EVENT_A2H_10H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L2_PENDING", IAP_EVENT_A3H_01H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_LDM_PENDING", IAP_EVENT_A3H_02H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.STALLS_L2_PENDING", IAP_EVENT_A3H_05H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L1D_PENDING", IAP_EVENT_A3H_08H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.STALLS_L1D_PENDING", IAP_EVENT_A3H_0CH) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ +__PMC_EV_ALIAS("ITLB.ITLB_FLUSH", IAP_EVENT_AEH_01H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_DATA_RD", IAP_EVENT_B0H_01H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_CODE_RD", IAP_EVENT_B0H_02H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_RFO", IAP_EVENT_B0H_04H) \ +__PMC_EV_ALIAS("OFFCORE_REQUESTS.ALL_DATA_RD", IAP_EVENT_B0H_08H) \ +__PMC_EV_ALIAS("UOPS_EXECUTED.CORE", IAP_EVENT_B1H_02H) \ +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_0", IAP_EVENT_B7H_01H) \ +__PMC_EV_ALIAS("OFF_CORE_RESPONSE_1", IAP_EVENT_BBH_01H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.DTLB_L1", IAP_EVENT_BCH_11H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.ITLB_L1", IAP_EVENT_BCH_21H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.DTLB_L2", IAP_EVENT_BCH_12H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.ITLB_L2", IAP_EVENT_BCH_22H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.DTLB_L3", IAP_EVENT_BCH_14H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.ITLB_L3", IAP_EVENT_BCH_24H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.DTLB_MEMORY", IAP_EVENT_BCH_18H) \ +__PMC_EV_ALIAS("PAGE_WALKER_LOADS.ITLB_MEMORY", IAP_EVENT_BCH_28H) \ +__PMC_EV_ALIAS("TLB_FLUSH.DTLB_THREAD", IAP_EVENT_BDH_01H) \ +__PMC_EV_ALIAS("TLB_FLUSH.STLB_ANY", IAP_EVENT_BDH_20H) \ +__PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_00H) \ +__PMC_EV_ALIAS("INST_RETIRED.PREC_DIST", IAP_EVENT_C0H_01H) \ +__PMC_EV_ALIAS("OTHER_ASSISTS.AVX_TO_SSE", IAP_EVENT_C1H_08H) \ +__PMC_EV_ALIAS("OTHER_ASSISTS.SSE_TO_AVX", IAP_EVENT_C1H_10H) \ +__PMC_EV_ALIAS("OTHER_ASSISTS.ANY_WB_ASSIST", IAP_EVENT_C1H_40H) \ +__PMC_EV_ALIAS("UOPS_RETIRED.ALL", IAP_EVENT_C2H_01H) \ +__PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \ +__PMC_EV_ALIAS("MACHINE_CLEARS.MEMORY_ORDERING", IAP_EVENT_C3H_02H) \ +__PMC_EV_ALIAS("MACHINE_CLEARS.SMC", IAP_EVENT_C3H_04H) \ +__PMC_EV_ALIAS("MACHINE_CLEARS.MASKMOV", IAP_EVENT_C3H_20H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_00H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.CONDITIONAL", IAP_EVENT_C4H_01H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_CALL", IAP_EVENT_C4H_02H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.ALL_BRANCHES", IAP_EVENT_C4H_04H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_RETURN", IAP_EVENT_C4H_08H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.NOT_TAKEN", IAP_EVENT_C4H_10H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.NEAR_TAKEN", IAP_EVENT_C4H_20H) \ +__PMC_EV_ALIAS("BR_INST_RETIRED.FAR_BRANCH", IAP_EVENT_C4H_40H) \ +__PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \ +__PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_01H) \ +__PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_04H) \ +__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_TAKEN", IAP_EVENT_C5H_20H) \ +__PMC_EV_ALIAS("FP_ASSIST.X87_OUTPUT", IAP_EVENT_CAH_02H) \ +__PMC_EV_ALIAS("FP_ASSIST.X87_INPUT", IAP_EVENT_CAH_04H) \ +__PMC_EV_ALIAS("FP_ASSIST.SIMD_OUTPUT", IAP_EVENT_CAH_08H) \ +__PMC_EV_ALIAS("FP_ASSIST.SIMD_INPUT", IAP_EVENT_CAH_10H) \ +__PMC_EV_ALIAS("FP_ASSIST.ANY", IAP_EVENT_CAH_1EH) \ +__PMC_EV_ALIAS("ROB_MISC_EVENTS.LBR_INSERTS", IAP_EVENT_CCH_20H) \ +__PMC_EV_ALIAS("MEM_TRANS_RETIRED.LOAD_LATENCY", IAP_EVENT_CDH_01H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.LOADS", IAP_EVENT_D0H_01H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.STORES", IAP_EVENT_D0H_02H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.STLB_MISS", IAP_EVENT_D0H_10H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.LOCK", IAP_EVENT_D0H_20H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT", IAP_EVENT_D0H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_LOADS", IAP_EVENT_D0H_41H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_STORES", IAP_EVENT_D0H_42H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL", IAP_EVENT_D0H_80H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_MISS", IAP_EVENT_D1H_08H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_MISS", IAP_EVENT_D1H_10H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L3_MISS", IAP_EVENT_D1H_20H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS", \ + IAP_EVENT_D2H_01H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT", \ + IAP_EVENT_D2H_02H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM", \ + IAP_EVENT_D2H_04H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_NONE", \ + IAP_EVENT_D2H_08H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.ALL", \ + IAP_EVENT_D2H_0FH) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM", \ + IAP_EVENT_D3H_01H) \ +__PMC_EV_ALIAS("BACLEARS.ANY", IAP_EVENT_E6H_1FH) \ +__PMC_EV_ALIAS("L2_TRANS.DEMAND_DATA_RD", IAP_EVENT_F0H_01H) \ +__PMC_EV_ALIAS("L2_TRANS.RFO", IAP_EVENT_F0H_02H) \ +__PMC_EV_ALIAS("L2_TRANS.CODE_RD", IAP_EVENT_F0H_04H) \ +__PMC_EV_ALIAS("L2_TRANS.ALL_PF", IAP_EVENT_F0H_08H) \ +__PMC_EV_ALIAS("L2_TRANS.L1D_WB", IAP_EVENT_F0H_10H) \ +__PMC_EV_ALIAS("L2_TRANS.L2_FILL", IAP_EVENT_F0H_20H) \ +__PMC_EV_ALIAS("L2_TRANS.L2_WB", IAP_EVENT_F0H_40H) \ +__PMC_EV_ALIAS("L2_TRANS.ALL_REQUESTS", IAP_EVENT_F0H_80H) \ +__PMC_EV_ALIAS("L2_LINES_IN.I", IAP_EVENT_F1H_01H) \ +__PMC_EV_ALIAS("L2_LINES_IN.S", IAP_EVENT_F1H_02H) \ +__PMC_EV_ALIAS("L2_LINES_IN.E", IAP_EVENT_F1H_04H) \ +__PMC_EV_ALIAS("L2_LINES_IN.ALL", IAP_EVENT_F1H_07H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_CLEAN", IAP_EVENT_F2H_05H) \ +__PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_06H) + + #define __PMC_EV_ALIAS_HASWELL() \ -__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \ __PMC_EV_ALIAS("LD_BLOCKS.STORE_FORWARD", IAP_EVENT_03H_02H) \ +__PMC_EV_ALIAS("LD_BLOCKS.NO_SR", IAP_EVENT_03H_08H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.LOADS", IAP_EVENT_05H_01H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.STORES", IAP_EVENT_05H_02H) \ __PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", IAP_EVENT_07H_01H) \ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_08H_01H)\ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED_4K", IAP_EVENT_08H_02H) \ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4K", \ - IAP_EVENT_08H_02H) \ + IAP_EVENT_08H_04H) \ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_0EH) \ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_DURATION", IAP_EVENT_08H_10H) \ __PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT_4K", IAP_EVENT_08H_20H) \ @@ -2592,7 +2826,7 @@ __PMC_EV_ALIAS("INT_MISC.RECOVERY_CYCLES", IAP_EVENT_0DH_03H) \ __PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \ __PMC_EV_ALIAS("UOPS_ISSUED.FLAGS_MERGE", IAP_EVENT_0EH_10H) \ __PMC_EV_ALIAS("UOPS_ISSUED.SLOW_LEA", IAP_EVENT_0EH_20H) \ -__PMC_EV_ALIAS("UOPS_ISSUED.SiNGLE_MUL", IAP_EVENT_0EH_40H) \ +__PMC_EV_ALIAS("UOPS_ISSUED.SINGLE_MUL", IAP_EVENT_0EH_40H) \ __PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_MISS", IAP_EVENT_24H_21H) \ __PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_HIT", IAP_EVENT_24H_41H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_E1H) \ @@ -2708,6 +2942,8 @@ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L2_PENDING", IAP_EVENT_A3H_01H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_LDM_PENDING", IAP_EVENT_A3H_02H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.STALLS_L2_PENDING", IAP_EVENT_A3H_05H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L1D_PENDING", IAP_EVENT_A3H_08H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.STALLS_L1D_PENDING", IAP_EVENT_A3H_0CH) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ __PMC_EV_ALIAS("ITLB.ITLB_FLUSH", IAP_EVENT_AEH_01H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_DATA_RD", IAP_EVENT_B0H_01H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS.DEMAND_CODE_RD", IAP_EVENT_B0H_02H) \ @@ -2727,7 +2963,7 @@ __PMC_EV_ALIAS("PAGE_WALKER_LOADS.ITLB_MEMORY", IAP_EVENT_BCH_28H) \ __PMC_EV_ALIAS("TLB_FLUSH.DTLB_THREAD", IAP_EVENT_BDH_01H) \ __PMC_EV_ALIAS("TLB_FLUSH.STLB_ANY", IAP_EVENT_BDH_20H) \ __PMC_EV_ALIAS("INST_RETIRED.ANY_P", IAP_EVENT_C0H_00H) \ -__PMC_EV_ALIAS("INST_RETIRED.ALL", IAP_EVENT_C0H_01H) \ +__PMC_EV_ALIAS("INST_RETIRED.PREC_DIST", IAP_EVENT_C0H_01H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.AVX_TO_SSE", IAP_EVENT_C1H_08H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.SSE_TO_AVX", IAP_EVENT_C1H_10H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.ANY_WB_ASSIST", IAP_EVENT_C1H_40H) \ @@ -2747,6 +2983,7 @@ __PMC_EV_ALIAS("BR_INST_RETIRED.FAR_BRANCH", IAP_EVENT_C4H_40H) \ __PMC_EV_ALIAS("BR_MISP_RETIRED.ALL_BRANCHES", IAP_EVENT_C5H_00H) \ __PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_01H) \ __PMC_EV_ALIAS("BR_MISP_RETIRED.CONDITIONAL", IAP_EVENT_C5H_04H) \ +__PMC_EV_ALIAS("BR_MISP_RETIRED.NEAR_TAKEN", IAP_EVENT_C5H_20H) \ __PMC_EV_ALIAS("FP_ASSIST.X87_OUTPUT", IAP_EVENT_CAH_02H) \ __PMC_EV_ALIAS("FP_ASSIST.X87_INPUT", IAP_EVENT_CAH_04H) \ __PMC_EV_ALIAS("FP_ASSIST.SIMD_OUTPUT", IAP_EVENT_CAH_08H) \ @@ -2759,11 +2996,15 @@ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STORES", IAP_EVENT_D0H_02H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STLB_MISS", IAP_EVENT_D0H_10H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.LOCK", IAP_EVENT_D0H_20H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT", IAP_EVENT_D0H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_LOADS", IAP_EVENT_D0H_41H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_STORES", IAP_EVENT_D0H_42H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL", IAP_EVENT_D0H_80H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_MISS", IAP_EVENT_D1H_08H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_MISS", IAP_EVENT_D1H_10H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L3_MISS", IAP_EVENT_D1H_20H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS", \ IAP_EVENT_D2H_01H) \ @@ -2795,21 +3036,30 @@ __PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_06H) #define __PMC_EV_ALIAS_IVYBRIDGE() \ -__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \ __PMC_EV_ALIAS("LD_BLOCKS.STORE_FORWARD", IAP_EVENT_03H_02H) \ +__PMC_EV_ALIAS("LD_BLOCKS.NO_SR", IAP_EVENT_03H_08H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.LOADS", IAP_EVENT_05H_01H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.STORES", IAP_EVENT_05H_02H) \ __PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", IAP_EVENT_07H_01H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK", \ - IAP_EVENT_08H_81H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_WALK_COMPLETED", \ - IAP_EVENT_08H_82H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_WALK_DURATION", \ - IAP_EVENT_08H_84H) \ +__PMC_EV_ALIAS("INT_MISC.RECOVERY_CYCLES", IAP_EVENT_0DH_03H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_08H_81H)\ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_82H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_DURATION", IAP_EVENT_08H_84H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_PG_WALK_DURATION", \ + IAP_EVENT_08H_88H) \ __PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \ __PMC_EV_ALIAS("UOPS_ISSUED.FLAGS_MERGE", IAP_EVENT_0EH_10H) \ __PMC_EV_ALIAS("UOPS_ISSUED.SLOW_LEA", IAP_EVENT_0EH_20H) \ __PMC_EV_ALIAS("UOPS_ISSUED.SINGLE_MUL", IAP_EVENT_0EH_40H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED_DOUBLE", \ + IAP_EVENT_10H_10H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR_SINGLE", \ + IAP_EVENT_10H_20H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_PACKED_SINGLE", IAP_EVENT_10H_40H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SCALAR_DOUBLE", IAP_EVENT_10H_80H) \ +__PMC_EV_ALIAS("SIMD_FP_256.PACKED_SINGLE", IAP_EVENT_11H_01H) \ +__PMC_EV_ALIAS("SIMD_FP_256.PACKED_DOUBLE", IAP_EVENT_11H_02H) \ __PMC_EV_ALIAS("ARITH.FPU_DIV_ACTIVE", IAP_EVENT_14H_01H) \ __PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_HIT", IAP_EVENT_24H_01H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_03H) \ @@ -2851,7 +3101,7 @@ __PMC_EV_ALIAS("MOVE_ELIMINATION.SIMD_ELIMINATED", IAP_EVENT_58H_08H) \ __PMC_EV_ALIAS("CPL_CYCLES.RING0", IAP_EVENT_5CH_01H) \ __PMC_EV_ALIAS("CPL_CYCLES.RING123", IAP_EVENT_5CH_02H) \ __PMC_EV_ALIAS("RS_EVENTS.EMPTY_CYCLES", IAP_EVENT_5EH_01H) \ -__PMC_EV_ALIAS("TLB_ACCESS.LOAD_STLB_HIT", IAP_EVENT_5FH_01H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.STLB_HIT", IAP_EVENT_5FH_04H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", \ IAP_EVENT_60H_01H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", \ @@ -2875,6 +3125,7 @@ __PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_ANY_UOPS", IAP_EVENT_79H_24H) \ __PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_4_UOPS", IAP_EVENT_79H_24H) \ __PMC_EV_ALIAS("IDQ.MITE_ALL_UOPS", IAP_EVENT_79H_3CH) \ __PMC_EV_ALIAS("ICACHE.MISSES", IAP_EVENT_80H_02H) \ +__PMC_EV_ALIAS("ICACHE.IFETCH_STALL", IAP_EVENT_80H_04H) \ __PMC_EV_ALIAS("ITLB_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_85H_01H) \ __PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \ __PMC_EV_ALIAS("ITLB_MISSES.WALK_DURATION", IAP_EVENT_85H_04H) \ @@ -2915,6 +3166,11 @@ __PMC_EV_ALIAS("RESOURCE_STALLS.ANY", IAP_EVENT_A2H_01H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.RS", IAP_EVENT_A2H_04H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.SB", IAP_EVENT_A2H_08H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.ROB", IAP_EVENT_A2H_10H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L2_PENDING", IAP_EVENT_A3H_01H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_LDM_PENDING", IAP_EVENT_A3H_02H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_NO_EXECUTE", IAP_EVENT_A3H_04H) \ +__PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L1D_PENDING", IAP_EVENT_A3H_08H) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.COUNT", IAP_EVENT_ABH_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.PENALTY_CYCLES", IAP_EVENT_ABH_02H) \ __PMC_EV_ALIAS("DSB_FILL.EXCEED_DSB_LINES", IAP_EVENT_ACH_08H) \ @@ -2934,6 +3190,7 @@ __PMC_EV_ALIAS("INST_RETIRED.ALL", IAP_EVENT_C0H_01H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.AVX_STORE", IAP_EVENT_C1H_08H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.AVX_TO_SSE", IAP_EVENT_C1H_10H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.SSE_TO_AVX", IAP_EVENT_C1H_20H) \ +__PMC_EV_ALIAS("OTHER_ASSISTS.WB", IAP_EVENT_C1H_80H) \ __PMC_EV_ALIAS("UOPS_RETIRED.ALL", IAP_EVENT_C2H_01H) \ __PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \ __PMC_EV_ALIAS("MACHINE_CLEARS.MEMORY_ORDERING", IAP_EVENT_C3H_02H) \ @@ -2966,11 +3223,17 @@ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STORES", IAP_EVENT_D0H_02H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STLB_MISS", IAP_EVENT_D0H_10H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.LOCK", IAP_EVENT_D0H_20H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT", IAP_EVENT_D0H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_STORES", IAP_EVENT_D0H_42H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL", IAP_EVENT_D0H_80H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL_LOADS", IAP_EVENT_D0H_81H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL_STORES", IAP_EVENT_D0H_82H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_MISS", IAP_EVENT_D1H_08H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_MISS", IAP_EVENT_D1H_10H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_MISS", IAP_EVENT_D1H_20H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS", \ IAP_EVENT_D2H_01H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT", \ @@ -2983,6 +3246,7 @@ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.ALL", \ IAP_EVENT_D2H_0FH) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM", \ IAP_EVENT_D3H_01H) \ +__PMC_EV_ALIAS("BACLEARS.ANY", IAP_EVENT_E6H_1FH) \ __PMC_EV_ALIAS("L2_TRANS.DEMAND_DATA_RD", IAP_EVENT_F0H_01H) \ __PMC_EV_ALIAS("L2_TRANS.RFO", IAP_EVENT_F0H_02H) \ __PMC_EV_ALIAS("L2_TRANS.CODE_RD", IAP_EVENT_F0H_04H) \ @@ -3004,21 +3268,30 @@ __PMC_EV_ALIAS("L2_LINES_OUT.PF_DIRTY", IAP_EVENT_F2H_08H) * Aliases for Ivy Bridge Xeon PMC events (325462-045US January 2013) */ #define __PMC_EV_ALIAS_IVYBRIDGE_XEON() \ -__PMC_EV_ALIAS_INTEL_ARCHITECTURAL() \ __PMC_EV_ALIAS("LD_BLOCKS.STORE_FORWARD", IAP_EVENT_03H_02H) \ +__PMC_EV_ALIAS("LD_BLOCKS.NO_SR", IAP_EVENT_03H_08H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.LOADS", IAP_EVENT_05H_01H) \ __PMC_EV_ALIAS("MISALIGN_MEM_REF.STORES", IAP_EVENT_05H_02H) \ __PMC_EV_ALIAS("LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", IAP_EVENT_07H_01H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_MISS_CAUSES_A_WALK", \ - IAP_EVENT_08H_81H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_WALK_COMPLETED", \ - IAP_EVENT_08H_82H) \ -__PMC_EV_ALIAS("DTLB_LOAD_MISSES.DEMAND_LD_WALK_DURATION", \ - IAP_EVENT_08H_84H) \ +__PMC_EV_ALIAS("INT_MISC.RECOVERY_CYCLES", IAP_EVENT_0DH_03H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_08H_81H)\ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_COMPLETED", IAP_EVENT_08H_82H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.WALK_DURATION", IAP_EVENT_08H_84H) \ +__PMC_EV_ALIAS("DTLB_LOAD_MISSES.LARGE_PG_WALK_DURATION", \ + IAP_EVENT_08H_88H) \ __PMC_EV_ALIAS("UOPS_ISSUED.ANY", IAP_EVENT_0EH_01H) \ __PMC_EV_ALIAS("UOPS_ISSUED.FLAGS_MERGE", IAP_EVENT_0EH_10H) \ __PMC_EV_ALIAS("UOPS_ISSUED.SLOW_LEA", IAP_EVENT_0EH_20H) \ __PMC_EV_ALIAS("UOPS_ISSUED.SINGLE_MUL", IAP_EVENT_0EH_40H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.X87", IAP_EVENT_10H_01H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_PACKED_DOUBLE", \ + IAP_EVENT_10H_10H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_FP_SCALAR_SINGLE", \ + IAP_EVENT_10H_20H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_PACKED_SINGLE", IAP_EVENT_10H_40H) \ +__PMC_EV_ALIAS("FP_COMP_OPS_EXE.SSE_SCALAR_DOUBLE", IAP_EVENT_10H_80H) \ +__PMC_EV_ALIAS("SIMD_FP_256.PACKED_SINGLE", IAP_EVENT_11H_01H) \ +__PMC_EV_ALIAS("SIMD_FP_256.PACKED_DOUBLE", IAP_EVENT_11H_02H) \ __PMC_EV_ALIAS("ARITH.FPU_DIV_ACTIVE", IAP_EVENT_14H_01H) \ __PMC_EV_ALIAS("L2_RQSTS.DEMAND_DATA_RD_HIT", IAP_EVENT_24H_01H) \ __PMC_EV_ALIAS("L2_RQSTS.ALL_DEMAND_DATA_RD", IAP_EVENT_24H_03H) \ @@ -3083,6 +3356,7 @@ __PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_ANY_UOPS", IAP_EVENT_79H_24H) \ __PMC_EV_ALIAS("IDQ.ALL_MITE_CYCLES_4_UOPS", IAP_EVENT_79H_24H) \ __PMC_EV_ALIAS("IDQ.MITE_ALL_UOPS", IAP_EVENT_79H_3CH) \ __PMC_EV_ALIAS("ICACHE.MISSES", IAP_EVENT_80H_02H) \ +__PMC_EV_ALIAS("ICACHE.IFETCH_STALL", IAP_EVENT_80H_04H) \ __PMC_EV_ALIAS("ITLB_MISSES.MISS_CAUSES_A_WALK", IAP_EVENT_85H_01H) \ __PMC_EV_ALIAS("ITLB_MISSES.WALK_COMPLETED", IAP_EVENT_85H_02H) \ __PMC_EV_ALIAS("ITLB_MISSES.WALK_DURATION", IAP_EVENT_85H_04H) \ @@ -3127,6 +3401,7 @@ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L2_PENDING", IAP_EVENT_A3H_01H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_LDM_PENDING", IAP_EVENT_A3H_02H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_NO_EXECUTE", IAP_EVENT_A3H_04H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L1D_PENDING", IAP_EVENT_A3H_08H) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.COUNT", IAP_EVENT_ABH_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.PENALTY_CYCLES", IAP_EVENT_ABH_02H) \ __PMC_EV_ALIAS("DSB_FILL.EXCEED_DSB_LINES", IAP_EVENT_ACH_08H) \ @@ -3146,6 +3421,7 @@ __PMC_EV_ALIAS("INST_RETIRED.ALL", IAP_EVENT_C0H_01H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.AVX_STORE", IAP_EVENT_C1H_08H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.AVX_TO_SSE", IAP_EVENT_C1H_10H) \ __PMC_EV_ALIAS("OTHER_ASSISTS.SSE_TO_AVX", IAP_EVENT_C1H_20H) \ +__PMC_EV_ALIAS("OTHER_ASSISTS.WB", IAP_EVENT_C1H_80H) \ __PMC_EV_ALIAS("UOPS_RETIRED.ALL", IAP_EVENT_C2H_01H) \ __PMC_EV_ALIAS("UOPS_RETIRED.RETIRE_SLOTS", IAP_EVENT_C2H_02H) \ __PMC_EV_ALIAS("MACHINE_CLEARS.MEMORY_ORDERING", IAP_EVENT_C3H_02H) \ @@ -3178,12 +3454,17 @@ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STORES", IAP_EVENT_D0H_02H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.STLB_MISS", IAP_EVENT_D0H_10H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.LOCK", IAP_EVENT_D0H_20H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT", IAP_EVENT_D0H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.SPLIT_STORES", IAP_EVENT_D0H_42H) \ __PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL", IAP_EVENT_D0H_80H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_MISS", IAP_EVENT_D1H_20H) \ -__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL_LOADS", IAP_EVENT_D0H_81H) \ +__PMC_EV_ALIAS("MEM_UOP_RETIRED.ALL_STORES", IAP_EVENT_D0H_82H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_HIT", IAP_EVENT_D1H_01H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_HIT", IAP_EVENT_D1H_02H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_HIT", IAP_EVENT_D1H_04H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L1_MISS", IAP_EVENT_D1H_08H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.L2_MISS", IAP_EVENT_D1H_10H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.LLC_MISS", IAP_EVENT_D1H_20H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_RETIRED.HIT_LFB", IAP_EVENT_D1H_40H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS", \ IAP_EVENT_D2H_01H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT", \ @@ -3194,8 +3475,10 @@ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_NONE", \ IAP_EVENT_D2H_08H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM", \ IAP_EVENT_D3H_01H) \ +__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM", \ + IAP_EVENT_D3H_03H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.REMOTE_DRAM", \ - IAP_EVENT_D3H_04H) \ + IAP_EVENT_D3H_0CH) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.REMOTE_HITM", \ IAP_EVENT_D3H_10H) \ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.REMOTE_FWD", \ @@ -3353,6 +3636,7 @@ __PMC_EV_ALIAS("RESOURCE_STALLS.ROB", IAP_EVENT_A2H_10H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.FCSW", IAP_EVENT_A2H_20H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.MXCSR", IAP_EVENT_A2H_40H) \ __PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.COUNT", IAP_EVENT_ABH_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.PENALTY_CYCLES", IAP_EVENT_ABH_02H) \ __PMC_EV_ALIAS("DSB_FILL.OTHER_CANCEL", IAP_EVENT_ACH_02H) \ @@ -3586,6 +3870,7 @@ __PMC_EV_ALIAS("RESOURCE_STALLS.OTHER", IAP_EVENT_A2H_80H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L2_PENDING", IAP_EVENT_A3H_01H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_L1D_PENDING", IAP_EVENT_A3H_02H) \ __PMC_EV_ALIAS("CYCLE_ACTIVITY.CYCLES_NO_DISPATCH", IAP_EVENT_A3H_04H) \ +__PMC_EV_ALIAS("LSD.UOPS", IAP_EVENT_A8H_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.COUNT", IAP_EVENT_ABH_01H) \ __PMC_EV_ALIAS("DSB2MITE_SWITCHES.PENALTY_CYCLES", IAP_EVENT_ABH_02H) \ __PMC_EV_ALIAS("DSB_FILL.OTHER_CANCEL", IAP_EVENT_ACH_02H) \ diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index a846975..1812840 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -94,6 +94,7 @@ __PMC_CPU(INTEL_ATOM_SILVERMONT, 0x92, "Intel Atom Silvermont") \ __PMC_CPU(INTEL_NEHALEM_EX, 0x93, "Intel Nehalem Xeon 7500") \ __PMC_CPU(INTEL_WESTMERE_EX, 0x94, "Intel Westmere Xeon E7") \ + __PMC_CPU(INTEL_HASWELL_XEON, 0x95, "Intel Haswell Xeon E5 v3") \ __PMC_CPU(INTEL_XSCALE, 0x100, "Intel XScale") \ __PMC_CPU(MIPS_24K, 0x200, "MIPS 24K") \ __PMC_CPU(MIPS_OCTEON, 0x201, "Cavium Octeon") \ diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 8c92af1..09e53ad 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -258,6 +258,7 @@ SUBDIR+= pkg SUBDIR+= pmcannotate SUBDIR+= pmccontrol SUBDIR+= pmcstat +SUBDIR+= pmcstudy .endif .if ${MK_PORTSNAP} != "no" diff --git a/usr.sbin/pmcstudy/Makefile b/usr.sbin/pmcstudy/Makefile new file mode 100644 index 0000000..87a6d66 --- /dev/null +++ b/usr.sbin/pmcstudy/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/9/93 +# $FreeBSD$ + +PROG= pmcstudy +SRCS= pmcstudy.c eval_expr.c +CFLAGS+= -Wall -Werror + +BINDIR= /usr/bin + +.include <bsd.prog.mk> + diff --git a/usr.sbin/pmcstudy/eval_expr.c b/usr.sbin/pmcstudy/eval_expr.c new file mode 100644 index 0000000..c225391 --- /dev/null +++ b/usr.sbin/pmcstudy/eval_expr.c @@ -0,0 +1,717 @@ +/*- + * Copyright (c) 2015 Netflix Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * in this position and unchanged. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> +#include <ctype.h> +#include "eval_expr.h" +__FBSDID("$FreeBSD$"); + +static struct expression * +alloc_and_hook_expr(struct expression **exp_p, struct expression **last_p) +{ + struct expression *ex, *at; + + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + if (*exp_p == NULL) { + *exp_p = ex; + } + at = *last_p; + if (at == NULL) { + /* First one, its last */ + *last_p = ex; + } else { + /* Chain it to the end and update last */ + at->next = ex; + ex->prev = at; + *last_p = ex; + } + return (ex); +} + + +static int +validate_expr(struct expression *exp, int val1_is_set, int op_is_set, int val2_is_set, + int *op_cnt) +{ + int val1, op, val2; + int open_cnt; + val1 = op = val2 = 0; + if (val1_is_set) { + val1 = 1; + } + if (op_is_set) { + op = 1; + } + if (val2_is_set) { + val2 = 1; + } + open_cnt = *op_cnt; + if (exp == NULL) { + /* End of the road */ + if (val1 && op && val2 && (open_cnt == 0)) { + return(0); + } else { + return(1); + } + } + switch(exp->type) { + case TYPE_OP_PLUS: + case TYPE_OP_MINUS: + case TYPE_OP_MULT: + case TYPE_OP_DIVIDE: + if (val1 && op && val2) { + /* We are at x + y + + * collapse back to val/op + */ + val1 = 1; + op = 1; + val2 = 0; + } else if ((op == 0) && (val1)) { + op = 1; + } else { + printf("Op but no val1 set\n"); + return(-1); + } + break; + case TYPE_PARN_OPEN: + if (exp->next == NULL) { + printf("NULL after open paren\n"); + exit(-1); + } + if ((exp->next->type == TYPE_OP_PLUS) || + (exp->next->type == TYPE_OP_MINUS) || + (exp->next->type == TYPE_OP_DIVIDE) || + (exp->next->type == TYPE_OP_MULT)) { + printf("'( OP' -- not allowed\n"); + return(-1); + } + if (val1 && (op == 0)) { + printf("'Val (' -- not allowed\n"); + return(-1); + } + if (val1 && op && val2) { + printf("'Val OP Val (' -- not allowed\n"); + return(-1); + } + open_cnt++; + *op_cnt = open_cnt; + if (val1) { + if (validate_expr(exp->next, 0, 0, 0, op_cnt) == 0) { + val2 = 1; + } else { + return(-1); + } + } else { + return(validate_expr(exp->next, 0, 0, 0, op_cnt)); + } + break; + case TYPE_PARN_CLOSE: + open_cnt--; + *op_cnt = open_cnt; + if (val1 && op && val2) { + return(0); + } else { + printf("Found close paren and not complete\n"); + return(-1); + } + break; + case TYPE_VALUE_CON: + case TYPE_VALUE_PMC: + if (val1 == 0) { + val1 = 1; + } else if (val1 && op) { + val2 = 1; + } else { + printf("val1 set, val2 about to be set op empty\n"); + return(-1); + } + break; + default: + printf("unknown type %d\n", exp->type); + exit(-5); + break; + } + return(validate_expr(exp->next, val1, op, val2, op_cnt)); +} + +void +print_exp(struct expression *exp) +{ + if (exp == NULL) { + printf("\n"); + return; + } + switch(exp->type) { + case TYPE_OP_PLUS: + printf(" + "); + break; + case TYPE_OP_MINUS: + printf(" - "); + break; + case TYPE_OP_MULT: + printf(" * "); + break; + case TYPE_OP_DIVIDE: + printf(" / "); + break; + case TYPE_PARN_OPEN: + printf(" ( "); + break; + case TYPE_PARN_CLOSE: + printf(" ) "); + break; + case TYPE_VALUE_CON: + printf("%f", exp->value); + break; + case TYPE_VALUE_PMC: + printf("%s", exp->name); + break; + default: + printf("Unknown op %d\n", exp->type); + break; + } + print_exp(exp->next); +} + +static void +walk_back_and_insert_paren(struct expression **beg, struct expression *frm) +{ + struct expression *at, *ex; + + /* Setup our new open paren */ + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + ex->type = TYPE_PARN_OPEN; + /* Now lets place it */ + at = frm->prev; + if (at == *beg) { + /* We are inserting at the head of the list */ + in_beg: + ex->next = at; + at->prev = ex; + *beg = ex; + return; + } else if ((at->type == TYPE_VALUE_CON) || + (at->type == TYPE_VALUE_PMC)) { + /* Simple case we have a value in the previous position */ + in_mid: + ex->prev = at->prev; + ex->prev->next = ex; + ex->next = at; + at->prev = ex; + return; + } else if (at->type == TYPE_PARN_CLOSE) { + /* Skip through until we reach beg or all ( closes */ + int par_cnt=1; + + at = at->prev; + while(par_cnt) { + if (at->type == TYPE_PARN_CLOSE) { + par_cnt++; + } else if (at->type == TYPE_PARN_OPEN) { + par_cnt--; + if (par_cnt == 0) { + break; + } + } + at = at->prev; + } + if (at == *beg) { + /* At beginning we insert */ + goto in_beg; + } else { + goto in_mid; + } + } else { + printf("%s:Unexpected type:%d?\n", + __FUNCTION__, at->type); + exit(-1); + } +} + +static void +walk_fwd_and_insert_paren(struct expression *frm, struct expression **added) +{ + struct expression *at, *ex; + /* Setup our new close paren */ + ex = malloc(sizeof(struct expression)); + if (ex == NULL) { + printf("Out of memory in exp allocation\n"); + exit(-2); + } + memset(ex, 0, sizeof(struct expression)); + ex->type = TYPE_PARN_CLOSE; + *added = ex; + /* Now lets place it */ + at = frm->next; + if ((at->type == TYPE_VALUE_CON) || + (at->type == TYPE_VALUE_PMC)) { + /* Simple case we have a value in the previous position */ + insertit: + ex->next = at->next; + ex->prev = at; + at->next = ex; + return; + } else if (at->type == TYPE_PARN_OPEN) { + int par_cnt=1; + at = at->next; + while(par_cnt) { + if (at->type == TYPE_PARN_OPEN) { + par_cnt++; + } else if (at->type == TYPE_PARN_CLOSE) { + par_cnt--; + if (par_cnt == 0) { + break; + } + } + at = at->next; + } + goto insertit; + } else { + printf("%s:Unexpected type:%d?\n", + __FUNCTION__, + at->type); + exit(-1); + } +} + + +static void +add_precendence(struct expression **beg, struct expression *start, struct expression *end) +{ + /* + * Between start and end add () around any * or /. This + * is quite tricky since if there is a () set inside the + * list we need to skip over everything in the ()'s considering + * that just a value. + */ + struct expression *at, *newone; + int open_cnt; + + at = start; + open_cnt = 0; + while(at != end) { + if (at->type == TYPE_PARN_OPEN) { + open_cnt++; + } + if (at->type == TYPE_PARN_CLOSE) { + open_cnt--; + } + if (open_cnt == 0) { + if ((at->type == TYPE_OP_MULT) || + (at->type == TYPE_OP_DIVIDE)) { + walk_back_and_insert_paren(beg, at); + walk_fwd_and_insert_paren(at, &newone); + at = newone->next; + continue; + } + } + at = at->next; + } + +} + +static void +set_math_precidence(struct expression **beg, struct expression *exp, struct expression **stopped) +{ + struct expression *at, *start, *end; + int cnt_lower, cnt_upper; + /* + * Walk through and set any math precedence to + * get proper precedence we insert () around * / over + - + */ + end = NULL; + start = at = exp; + cnt_lower = cnt_upper = 0; + while(at) { + if (at->type == TYPE_PARN_CLOSE) { + /* Done with that paren */ + if (stopped) { + *stopped = at; + } + if (cnt_lower && cnt_upper) { + /* We have a mixed set ... add precedence between start/end */ + add_precendence(beg, start, end); + } + return; + } + if (at->type == TYPE_PARN_OPEN) { + set_math_precidence(beg, at->next, &end); + at = end; + continue; + } else if ((at->type == TYPE_OP_PLUS) || + (at->type == TYPE_OP_MINUS)) { + cnt_lower++; + } else if ((at->type == TYPE_OP_DIVIDE) || + (at->type == TYPE_OP_MULT)) { + cnt_upper++; + } + at = at->next; + } + if (cnt_lower && cnt_upper) { + add_precendence(beg, start, NULL); + } +} + +extern char **valid_pmcs; +extern int valid_pmc_cnt; + +static void +pmc_name_set(struct expression *at) +{ + int i, idx, fnd; + + if (at->name[0] == '%') { + /* Special number after $ gives index */ + idx = strtol(&at->name[1], NULL, 0); + if (idx >= valid_pmc_cnt) { + printf("Unknown PMC %s -- largest we have is $%d -- can't run your expression\n", + at->name, valid_pmc_cnt); + exit(-1); + } + strcpy(at->name, valid_pmcs[idx]); + } else { + for(i=0, fnd=0; i<valid_pmc_cnt; i++) { + if (strcmp(valid_pmcs[i], at->name) == 0) { + fnd = 1; + break; + } + } + if (!fnd) { + printf("PMC %s does not exist on this machine -- can't run your expression\n", + at->name); + exit(-1); + } + } +} + +struct expression * +parse_expression(char *str) +{ + struct expression *exp=NULL, *last=NULL, *at; + int open_par, close_par; + int op_cnt=0; + size_t siz, i, x; + /* + * Walk through a string expression and convert + * it to a linked list of actions. We do this by: + * a) Counting the open/close paren's, there must + * be a matching number. + * b) If we have balanced paren's then create a linked list + * of the operators, then we validate that expression further. + * c) Validating that we have: + * val OP val <or> + * val OP ( <and> + * inside every paran you have a: + * val OP val <or> + * val OP ( <recursively> + * d) A final optional step (not implemented yet) would be + * to insert the mathimatical precedence paran's. For + * the start we will just do the left to right evaluation and + * then later we can add this guy to add paran's to make it + * mathimatically correct... i.e instead of 1 + 2 * 3 we + * would translate it into 1 + ( 2 * 3). + */ + open_par = close_par = 0; + siz = strlen(str); + /* No trailing newline please */ + if (str[(siz-1)] == '\n') { + str[(siz-1)] = 0; + siz--; + } + for(i=0; i<siz; i++) { + if (str[i] == '(') { + open_par++; + } else if (str[i] == ')') { + close_par++; + } + } + if (open_par != close_par) { + printf("Invalid expression '%s' %d open paren's and %d close?\n", + str, open_par, close_par); + exit(-1); + } + for(i=0; i<siz; i++) { + if (str[i] == '(') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_PARN_OPEN; + } else if (str[i] == ')') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_PARN_CLOSE; + } else if (str[i] == ' ') { + /* Extra blank */ + continue; + } else if (str[i] == '\t') { + /* Extra tab */ + continue; + } else if (str[i] == '+') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_PLUS; + } else if (str[i] == '-') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_MINUS; + } else if (str[i] == '/') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_DIVIDE; + } else if (str[i] == '*') { + at = alloc_and_hook_expr(&exp, &last); + at->type = TYPE_OP_MULT; + } else { + /* Its a value or PMC constant */ + at = alloc_and_hook_expr(&exp, &last); + if (isdigit(str[i]) || (str[i] == '.')) { + at->type = TYPE_VALUE_CON; + } else { + at->type = TYPE_VALUE_PMC; + } + x = 0; + while ((str[i] != ' ') && + (str[i] != '\t') && + (str[i] != 0) && + (str[i] != ')') && + (str[i] != '(')) { + /* We collect the constant until a space or tab */ + at->name[x] = str[i]; + i++; + x++; + if (x >=(sizeof(at->name)-1)) { + printf("Value/Constant too long %d max:%d\n", + (int)x, (int)(sizeof(at->name)-1)); + exit(-3); + } + } + if (str[i] != 0) { + /* Need to back up and see the last char since + * the for will increment the loop. + */ + i--; + } + /* Now we have pulled the string, set it up */ + if (at->type == TYPE_VALUE_CON) { + at->state = STATE_FILLED; + at->value = strtod(at->name, NULL); + } else { + pmc_name_set(at); + } + } + } + /* Now lets validate its a workable expression */ + if (validate_expr(exp, 0, 0, 0, &op_cnt)) { + printf("Invalid expression\n"); + exit(-4); + } + set_math_precidence(&exp, exp, NULL); + return (exp); +} + + + +static struct expression * +gather_exp_to_paren_close(struct expression *exp, double *val_fill) +{ + /* + * I have been given ( ??? + * so I could see either + * ( + * or + * Val Op + * + */ + struct expression *lastproc; + double val; + + if (exp->type == TYPE_PARN_OPEN) { + lastproc = gather_exp_to_paren_close(exp->next, &val); + *val_fill = val; + } else { + *val_fill = run_expr(exp, 0, &lastproc); + } + return(lastproc); +} + + +double +run_expr(struct expression *exp, int initial_call, struct expression **lastone) +{ + /* + * We expect to find either + * a) A Open Paren + * or + * b) Val-> Op -> Val + * or + * c) Val-> Op -> Open Paren + */ + double val1, val2, res; + struct expression *op, *other_half, *rest; + + if (exp->type == TYPE_PARN_OPEN) { + op = gather_exp_to_paren_close(exp->next, &val1); + } else if(exp->type == TYPE_VALUE_CON) { + val1 = exp->value; + op = exp->next; + } else if (exp->type == TYPE_VALUE_PMC) { + val1 = exp->value; + op = exp->next; + } else { + printf("Illegal value in %s huh?\n", __FUNCTION__); + exit(-1); + } + if (op == NULL) { + return (val1); + } +more_to_do: + other_half = op->next; + if (other_half->type == TYPE_PARN_OPEN) { + rest = gather_exp_to_paren_close(other_half->next, &val2); + } else if(other_half->type == TYPE_VALUE_CON) { + val2 = other_half->value; + rest = other_half->next; + } else if (other_half->type == TYPE_VALUE_PMC) { + val2 = other_half->value; + rest = other_half->next; + } else { + printf("Illegal2 value in %s huh?\n", __FUNCTION__); + exit(-1); + } + switch(op->type) { + case TYPE_OP_PLUS: + res = val1 + val2; + break; + case TYPE_OP_MINUS: + res = val1 - val2; + break; + case TYPE_OP_MULT: + res = val1 * val2; + break; + case TYPE_OP_DIVIDE: + if (val2 != 0.0) + res = val1 / val2; + else { + printf("Division by zero averted\n"); + res = 1.0; + } + break; + default: + printf("Op is not an operator -- its %d\n", + op->type); + exit(-1); + break; + } + if (rest == NULL) { + if (lastone) { + *lastone = NULL; + } + return (res); + } + if ((rest->type == TYPE_PARN_CLOSE) && (initial_call == 0)) { + if (lastone) { + *lastone = rest->next; + } + return(res); + } + /* There is more, as in + * a + b + c + * where we just did a + b + * so now it becomes val1 is set to res and + * we need to proceed with the rest of it. + */ + val1 = res; + op = rest; + if ((op->type != TYPE_OP_PLUS) && + (op->type != TYPE_OP_MULT) && + (op->type != TYPE_OP_MINUS) && + (op->type != TYPE_OP_DIVIDE)) { + printf("%s ending on type:%d not an op??\n", __FUNCTION__, op->type); + return(res); + } + if (op) + goto more_to_do; + return (res); +} + +#ifdef STAND_ALONE_TESTING + +static double +calc_expr(struct expression *exp) +{ + struct expression *at; + double xx; + + /* First clear PMC's setting */ + for(at = exp; at != NULL; at = at->next) { + if (at->type == TYPE_VALUE_PMC) { + at->state = STATE_UNSET; + } + } + /* Now for all pmc's make up values .. here is where I would pull them */ + for(at = exp; at != NULL; at = at->next) { + if (at->type == TYPE_VALUE_PMC) { + at->value = (random() * 1.0); + at->state = STATE_FILLED; + if (at->value == 0.0) { + /* So we don't have div by 0 */ + at->value = 1.0; + } + } + } + /* Now lets calculate the expression */ + print_exp(exp); + xx = run_expr(exp, 1, NULL); + printf("Answer is %f\n", xx); + return(xx); +} + + +int +main(int argc, char **argv) +{ + struct expression *exp; + if (argc < 2) { + printf("Use %s expression\n", argv[0]); + return(-1); + } + exp = parse_expression(argv[1]); + printf("Now the calc\n"); + calc_expr(exp); + return(0); +} + +#endif diff --git a/usr.sbin/pmcstudy/eval_expr.h b/usr.sbin/pmcstudy/eval_expr.h new file mode 100644 index 0000000..f095513 --- /dev/null +++ b/usr.sbin/pmcstudy/eval_expr.h @@ -0,0 +1,58 @@ +#ifndef __eval_expr_h__ +#define __eval_expr_h__ +/*- + * Copyright (c) 2015 Netflix Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * in this position and unchanged. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ +__FBSDID("$FreeBSD$"); + +enum exptype { + TYPE_OP_PLUS, + TYPE_OP_MINUS, + TYPE_OP_MULT, + TYPE_OP_DIVIDE, + TYPE_PARN_OPEN, + TYPE_PARN_CLOSE, + TYPE_VALUE_CON, + TYPE_VALUE_PMC +}; + +#define STATE_UNSET 0 /* We have no setting yet in value */ +#define STATE_FILLED 1 /* We have filled in value */ + +struct expression { + struct expression *next; /* Next in expression. */ + struct expression *prev; /* Prev in expression. */ + double value; /* If there is a value to set */ + enum exptype type; /* What is it */ + uint8_t state; /* Current state if value type */ + char name[252]; /* If a PMC whats the name, con value*/ +}; + +struct expression *parse_expression(char *str); +double run_expr(struct expression *exp, int initial_call, struct expression **lastone); +void print_exp(struct expression *exp); +#endif diff --git a/usr.sbin/pmcstudy/pmcstudy.1 b/usr.sbin/pmcstudy/pmcstudy.1 new file mode 100644 index 0000000..ad779b9 --- /dev/null +++ b/usr.sbin/pmcstudy/pmcstudy.1 @@ -0,0 +1,65 @@ +.\" Copyright (c) 2015 +.\" Netflix Inc. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd Dec 2, 2014 +.Dt PMC_COUNTER_STUDY 1 +.Os +.Sh NAME +.Nm pmc_counter_study +.Nd Perform various study's on a systems overall PMC's. +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +The +.Nm +The pmc_counter_study program is designed to run various tests against +your systems performance. There are roughly 20-22 canned tests that +setup specific PMC's and then run various formulas on the output information. +These formulas can be found in Intel documentation "Using Intel Vtune +amplifier xe on NNN Generation Intel Core Processors". The NNN is either +2nd, 3rd or 4th generation i.e. Sandy Bridge, Ivy Bridge and Haswell. +Currently the program only works on these three Intel processor types. +You can see the complete list of formula's by running the program +with the -H option. If you know a formula name you can run it by +typing -e name. If you know a name and want what the formula is you +can run the program with -e name -h and the program will not run but +it will tell you what that name will do (if known). The -T option can +be used to test all PMC's that are known to your system. When running a +test you will want to specify -m N where N is the number of 1 second samples +to collect and analize (it bounds the time the test runs). Finally for +those that have there own ideas on what formulas that you want to run +you can type your own formula in with -E "formula". The formula can +declare directly the PMC's by name or you can use an abbreviation +%NNN. To find out the abbreviations on your system you may run +pmc_counter_study -L and it will tell you each PMC name and the +abbreviation you can use. An example of a formula of your own might +be -E "FP_ASSIST.ANY / INST_RETIRED.ANY_P" <or short hand on Haswell> +-E " %176 / %150". You must have spaces between each entry and +you may use paraenthisis to prioritize the operators. Add (+), Subtract (-1), +Divide (/) and Multiplication (*) is supported. You may also introduce +constant numbers as well. So for example you can do a standard efficency +test like -E "UOPS_RETIRED.RETIRE_SLOTS / (4 * CPU_CLK_UNHALTED.THREAD_P)". + diff --git a/usr.sbin/pmcstudy/pmcstudy.c b/usr.sbin/pmcstudy/pmcstudy.c new file mode 100644 index 0000000..6547489 --- /dev/null +++ b/usr.sbin/pmcstudy/pmcstudy.c @@ -0,0 +1,2425 @@ +/*- + * Copyright (c) 2014, 2015 Netflix Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * in this position and unchanged. + * 2. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <strings.h> +#include <sys/errno.h> +#include <signal.h> +#include <sys/wait.h> +#include <getopt.h> +#include "eval_expr.h" +__FBSDID("$FreeBSD$"); + +#define MAX_COUNTER_SLOTS 1024 +#define MAX_NLEN 64 +#define MAX_CPU 64 +static int verbose = 0; + +extern char **environ; +extern struct expression *master_exp; +struct expression *master_exp=NULL; + +#define PMC_INITIAL_ALLOC 512 +extern char **valid_pmcs; +char **valid_pmcs = NULL; +extern int valid_pmc_cnt; +int valid_pmc_cnt=0; +extern int pmc_allocated_cnt; +int pmc_allocated_cnt=0; + +/* + * The following two varients on popen and pclose with + * the cavet that they get you the PID so that you + * can supply it to pclose so it can send a SIGTERM + * to the process. + */ +static FILE * +my_popen(const char *command, const char *dir, pid_t *p_pid) +{ + FILE *io_out, *io_in; + int pdesin[2], pdesout[2]; + char *argv[4]; + pid_t pid; + char cmd[4]; + char cmd2[1024]; + char arg1[4]; + + if ((strcmp(dir, "r") != 0) && + (strcmp(dir, "w") != 0)) { + errno = EINVAL; + return(NULL); + } + if (pipe(pdesin) < 0) + return (NULL); + + if (pipe(pdesout) < 0) { + (void)close(pdesin[0]); + (void)close(pdesin[1]); + return (NULL); + } + strcpy(cmd, "sh"); + strcpy(arg1, "-c"); + strcpy(cmd2, command); + argv[0] = cmd; + argv[1] = arg1; + argv[2] = cmd2; + argv[3] = NULL; + + switch (pid = fork()) { + case -1: /* Error. */ + (void)close(pdesin[0]); + (void)close(pdesin[1]); + (void)close(pdesout[0]); + (void)close(pdesout[1]); + return (NULL); + /* NOTREACHED */ + case 0: /* Child. */ + /* Close out un-used sides */ + (void)close(pdesin[1]); + (void)close(pdesout[0]); + /* Now prepare the stdin of the process */ + close(0); + (void)dup(pdesin[0]); + (void)close(pdesin[0]); + /* Now prepare the stdout of the process */ + close(1); + (void)dup(pdesout[1]); + /* And lets do stderr just in case */ + close(2); + (void)dup(pdesout[1]); + (void)close(pdesout[1]); + /* Now run it */ + execve("/bin/sh", argv, environ); + exit(127); + /* NOTREACHED */ + } + /* Parent; assume fdopen can't fail. */ + /* Store the pid */ + *p_pid = pid; + if (strcmp(dir, "r") != 0) { + io_out = fdopen(pdesin[1], "w"); + (void)close(pdesin[0]); + (void)close(pdesout[0]); + (void)close(pdesout[1]); + return(io_out); + } else { + /* Prepare the input stream */ + io_in = fdopen(pdesout[0], "r"); + (void)close(pdesout[1]); + (void)close(pdesin[0]); + (void)close(pdesin[1]); + return (io_in); + } +} + +/* + * pclose -- + * Pclose returns -1 if stream is not associated with a `popened' command, + * if already `pclosed', or waitpid returns an error. + */ +static void +my_pclose(FILE *io, pid_t the_pid) +{ + int pstat; + pid_t pid; + + /* + * Find the appropriate file pointer and remove it from the list. + */ + (void)fclose(io); + /* Die if you are not dead! */ + kill(the_pid, SIGTERM); + do { + pid = wait4(the_pid, &pstat, 0, (struct rusage *)0); + } while (pid == -1 && errno == EINTR); +} + +struct counters { + struct counters *next_cpu; + char counter_name[MAX_NLEN]; /* Name of counter */ + int cpu; /* CPU we are on */ + int pos; /* Index we are filling to. */ + uint64_t vals[MAX_COUNTER_SLOTS]; /* Last 64 entries */ + uint64_t sum; /* Summary of entries */ +}; + +extern struct counters *glob_cpu[MAX_CPU]; +struct counters *glob_cpu[MAX_CPU]; + +extern struct counters *cnts; +struct counters *cnts=NULL; + +extern int ncnts; +int ncnts=0; + +extern int (*expression)(struct counters *, int); +int (*expression)(struct counters *, int); + +static const char *threshold=NULL; +static const char *command; + +struct cpu_entry { + const char *name; + const char *thresh; + const char *command; + int (*func)(struct counters *, int); +}; + + +struct cpu_type { + char cputype[32]; + int number; + struct cpu_entry *ents; + void (*explain)(const char *name); +}; +extern struct cpu_type the_cpu; +struct cpu_type the_cpu; + +static void +explain_name_sb(const char *name) +{ + const char *mythresh; + if (strcmp(name, "allocstall1") == 0) { + printf("Examine PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "allocstall2") == 0) { + printf("Examine PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "br_miss") == 0) { + printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine ((MEM_LOAD_RETIRED.L3_HIT * 26) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P\n"); + printf("**Note we have it labeled MEM_LOAD_UOPS_RETIRED.LLC_HIT not MEM_LOAD_RETIRED.L3_HIT\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "frontendstall") == 0) { + printf("Examine IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4)\n"); + mythresh = "thresh >= .15"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (CPU_CLK_UNHALTED.THREAD_P * 4)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .9"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "dtlbmissstore") == 0) { + printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .05"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + +static void +explain_name_ib(const char *name) +{ + const char *mythresh; + if (strcmp(name, "br_miss") == 0) { + printf("Examine ((BR_MISP_RETIRED.ALL_BRANCHES /(BR_MISP_RETIRED.ALL_BRANCHES +\n"); + printf(" MACHINE_CLEAR.COUNT) * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES)\n"); + printf("/ (4 * CPU_CLK_UNHALTED.THREAD))))\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .9"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine (MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "itlbmiss") == 0) { + printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "icachemiss") == 0) { + printf("Examine (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION)/ CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "lcpstall") == 0) { + printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "datashare") == 0) { + printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) *\n"); + printf(" LD_BLOCKS.NO_SR)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissstore") == 0) { + printf("Examine (((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + + +static void +explain_name_has(const char *name) +{ + const char *mythresh; + if (strcmp(name, "eff1") == 0) { + printf("Examine (UOPS_RETIRED.RETIRE_SLOTS)/(4 *CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh < .75"; + } else if (strcmp(name, "eff2") == 0) { + printf("Examine CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P\n"); + mythresh = "thresh > 1.0"; + } else if (strcmp(name, "itlbmiss") == 0) { + printf("Examine ITLB_MISSES.WALK_DURATION / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "icachemiss") == 0) { + printf("Examine (36 * ICACHE.MISSES)/ CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "lcpstall") == 0) { + printf("Examine ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "cache1") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "cache2") == 0) { + printf("Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) + \n"); + printf(" (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84))\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "contested") == 0) { + printf("Examine (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "datashare") == 0) { + printf("Examine (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 72)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh > .05"; + } else if (strcmp(name, "blockstorefwd") == 0) { + printf("Examine (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "splitload") == 0) { + printf("Examine (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "splitstore") == 0) { + printf("Examine MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES\n"); + mythresh = "thresh >= .01"; + } else if (strcmp(name, "aliasing_4k") == 0) { + printf("Examine (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "dtlbmissload") == 0) { + printf("Examine (((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION)\n"); + printf(" / CPU_CLK_UNHALTED.THREAD_P)\n"); + mythresh = "thresh >= .1"; + } else if (strcmp(name, "br_miss") == 0) { + printf("Examine (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD\n"); + mythresh = "thresh >= .2"; + } else if (strcmp(name, "clears") == 0) { + printf("Examine ((MACHINE_CLEARS.MEMORY_ORDERING + \n"); + printf(" MACHINE_CLEARS.SMC + \n"); + printf(" MACHINE_CLEARS.MASKMOV ) * 100 ) / CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "thresh >= .02"; + } else if (strcmp(name, "microassist") == 0) { + printf("Examine IDQ.MS_CYCLES / (4 * CPU_CLK_UNHALTED.THREAD_P)\n"); + printf("***We use IDQ.MS_UOPS,cmask=1 to get cycles\n"); + mythresh = "thresh >= .05"; + } else if (strcmp(name, "fpassist") == 0) { + printf("Examine FP_ASSIST.ANY/INST_RETIRED.ANY_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistavx") == 0) { + printf("Examine (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else if (strcmp(name, "otherassistsse") == 0) { + printf("Examine (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P\n"); + mythresh = "look for a excessive value"; + } else { + printf("Unknown name:%s\n", name); + mythresh = "unknown entry"; + } + printf("If the value printed is %s we may have the ability to improve performance\n", mythresh); +} + + +static struct counters * +find_counter(struct counters *base, const char *name) +{ + struct counters *at; + int len; + + at = base; + len = strlen(name); + while(at) { + if (strncmp(at->counter_name, name, len) == 0) { + return(at); + } + at = at->next_cpu; + } + printf("Can't find counter %s\n", name); + printf("We have:\n"); + at = base; + while(at) { + printf("- %s\n", at->counter_name); + at = at->next_cpu; + } + exit(-1); +} + +static int +allocstall1(struct counters *cpu, int pos) +{ +/* 1 - PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW/CPU_CLK_UNHALTED.THREAD_P (thresh > .05)*/ + int ret; + struct counters *partial; + struct counters *unhalt; + double un, par, res; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + partial = find_counter(cpu, "PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW"); + if (pos != -1) { + par = partial->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + par = partial->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = par/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +allocstall2(struct counters *cpu, int pos) +{ +/* 2 - PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES/CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *partial; + struct counters *unhalt; + double un, par, res; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + partial = find_counter(cpu, "PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP"); + if (pos != -1) { + par = partial->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + par = partial->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = par/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +br_mispredict(struct counters *cpu, int pos) +{ + struct counters *brctr; + struct counters *unhalt; + int ret; +/* 3 - (20 * BR_MISP_RETIRED.ALL_BRANCHES)/CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + double br, un, con, res; + con = 20.0; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES"); + if (pos != -1) { + br = brctr->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + br = brctr->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * br)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +br_mispredictib(struct counters *cpu, int pos) +{ + struct counters *brctr; + struct counters *unhalt; + struct counters *clear, *clear2, *clear3; + struct counters *uops; + struct counters *recv; + struct counters *iss; +/* "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1",*/ + int ret; + /* + * (BR_MISP_RETIRED.ALL_BRANCHES / + * (BR_MISP_RETIRED.ALL_BRANCHES + + * MACHINE_CLEAR.COUNT) * + * ((UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) / (4 * CPU_CLK_UNHALTED.THREAD))) + * + */ + double br, cl, cl2, cl3, uo, re, un, con, res, is; + con = 4.0; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + brctr = find_counter(cpu, "BR_MISP_RETIRED.ALL_BRANCHES"); + clear = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING"); + clear2 = find_counter(cpu, "MACHINE_CLEARS.SMC"); + clear3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV"); + uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS"); + iss = find_counter(cpu, "UOPS_ISSUED.ANY"); + recv = find_counter(cpu, "INT_MISC.RECOVERY_CYCLES"); + if (pos != -1) { + br = brctr->vals[pos] * 1.0; + cl = clear->vals[pos] * 1.0; + cl2 = clear2->vals[pos] * 1.0; + cl3 = clear3->vals[pos] * 1.0; + uo = uops->vals[pos] * 1.0; + re = recv->vals[pos] * 1.0; + is = iss->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + br = brctr->sum * 1.0; + cl = clear->sum * 1.0; + cl2 = clear2->sum * 1.0; + cl3 = clear3->sum * 1.0; + uo = uops->sum * 1.0; + re = recv->sum * 1.0; + is = iss->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (br/(br + cl + cl2 + cl3) * ((is - uo + con * re) / (con * un))); + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitloadib(struct counters *cpu, int pos) +{ + int ret; + struct counters *mem; + struct counters *l1d, *ldblock; + struct counters *unhalt; + double un, memd, res, l1, ldb; + /* + * ((L1D_PEND_MISS.PENDING / MEM_LOAD_UOPS_RETIRED.L1_MISS) * LD_BLOCKS.NO_SR) / CPU_CLK_UNHALTED.THREAD_P + * "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1", + */ + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.L1_MISS"); + l1d = find_counter(cpu, "L1D_PEND_MISS.PENDING"); + ldblock = find_counter(cpu, "LD_BLOCKS.NO_SR"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + l1 = l1d->vals[pos] * 1.0; + ldb = ldblock->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + l1 = l1d->sum * 1.0; + ldb = ldblock->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((l1 / memd) * ldb)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitload(struct counters *cpu, int pos) +{ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; +/* 4 - (MEM_UOP_RETIRED.SPLIT_LOADS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .1)*/ + + con = 5.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_LOADS"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +splitstore(struct counters *cpu, int pos) +{ + /* 5 - MEM_UOP_RETIRED.SPLIT_STORES / MEM_UOP_RETIRED.ALL_STORES (thresh > 0.01) */ + int ret; + struct counters *mem_split; + struct counters *mem_stores; + double memsplit, memstore, res; + mem_split = find_counter(cpu, "MEM_UOP_RETIRED.SPLIT_STORES"); + mem_stores = find_counter(cpu, "MEM_UOP_RETIRED.ALL_STORES"); + if (pos != -1) { + memsplit = mem_split->vals[pos] * 1.0; + memstore = mem_stores->vals[pos] * 1.0; + } else { + memsplit = mem_split->sum * 1.0; + memstore = mem_stores->sum * 1.0; + } + res = memsplit/memstore; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +contested(struct counters *cpu, int pos) +{ + /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; + + con = 60.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +contested_has(struct counters *cpu, int pos) +{ + /* 6 - (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84) / CPU_CLK_UNHALTED.THREAD_P (thresh >.05) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, memd, res; + + con = 84.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + memd = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + memd = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (memd * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +blockstoreforward(struct counters *cpu, int pos) +{ + /* 7 - (LD_BLOCKS_STORE_FORWARD * 13) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .05)*/ + int ret; + struct counters *ldb; + struct counters *unhalt; + double con, un, ld, res; + + con = 13.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ldb = find_counter(cpu, "LD_BLOCKS_STORE_FORWARD"); + if (pos != -1) { + ld = ldb->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ld = ldb->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ld * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache2(struct counters *cpu, int pos) +{ + /* ** Suspect *** + * 8 - ((MEM_LOAD_RETIRED.L3_HIT * 26) + (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 43) + + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 60)) / CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem1, *mem2, *mem3; + struct counters *unhalt; + double con1, con2, con3, un, me_1, me_2, me_3, res; + + con1 = 26.0; + con2 = 43.0; + con3 = 60.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); +/* Call for MEM_LOAD_RETIRED.L3_HIT possibly MEM_LOAD_UOPS_RETIRED.LLC_HIT ?*/ + mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + me_1 = mem1->vals[pos] * 1.0; + me_2 = mem2->vals[pos] * 1.0; + me_3 = mem3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me_1 = mem1->sum * 1.0; + me_2 = mem2->sum * 1.0; + me_3 = mem3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((me_1 * con1) + (me_2 * con2) + (me_3 * con3))/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +datasharing(struct counters *cpu, int pos) +{ + /* + * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, res, me, un; + + con = 43.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +datasharing_has(struct counters *cpu, int pos) +{ + /* + * (MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT * 43)/ CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, res, me, un; + + con = 72.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +cache2ib(struct counters *cpu, int pos) +{ + /* + * (29 * MEM_LOAD_UOPS_RETIRED.LLC_HIT / CPU_CLK_UNHALTED.THREAD_P (thresh >.2) + */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 29.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * me)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache2has(struct counters *cpu, int pos) +{ + /* + * Examine ((MEM_LOAD_UOPS_RETIRED.LLC_HIT * 36) + \ + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT * 72) + + * (MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM * 84)) + * / CPU_CLK_UNHALTED.THREAD_P + */ + int ret; + struct counters *mem1, *mem2, *mem3; + struct counters *unhalt; + double con1, con2, con3, un, me1, me2, me3, res; + + con1 = 36.0; + con2 = 72.0; + con3 = 84.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem1 = find_counter(cpu, "MEM_LOAD_UOPS_RETIRED.LLC_HIT"); + mem2 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT"); + mem3 = find_counter(cpu, "MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM"); + if (pos != -1) { + me1 = mem1->vals[pos] * 1.0; + me2 = mem2->vals[pos] * 1.0; + me3 = mem3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me1 = mem1->sum * 1.0; + me2 = mem2->sum * 1.0; + me3 = mem3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((me1 * con1) + (me2 * con2) + (me3 * con3))/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache1(struct counters *cpu, int pos) +{ + /* 9 - (MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 180.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +cache1ib(struct counters *cpu, int pos) +{ + /* 9 - (MEM_LOAD_UOPS_L3_MISS_RETIRED.LCOAL_DRAM * 180) / CPU_CLK_UNHALTED.THREAD_P (thresh >= .2) */ + int ret; + struct counters *mem; + struct counters *unhalt; + double con, un, me, res; + + con = 180.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + mem = find_counter(cpu, "MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM"); + if (pos != -1) { + me = mem->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + me = mem->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (me * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + + +static int +dtlb_missload(struct counters *cpu, int pos) +{ + /* 10 - ((DTLB_LOAD_MISSES.STLB_HIT * 7) + DTLB_LOAD_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P (t >=.1) */ + int ret; + struct counters *dtlb_m, *dtlb_d; + struct counters *unhalt; + double con, un, d1, d2, res; + + con = 7.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + dtlb_m = find_counter(cpu, "DTLB_LOAD_MISSES.STLB_HIT"); + dtlb_d = find_counter(cpu, "DTLB_LOAD_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = dtlb_m->vals[pos] * 1.0; + d2 = dtlb_d->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = dtlb_m->sum * 1.0; + d2 = dtlb_d->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((d1 * con) + d2)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +dtlb_missstore(struct counters *cpu, int pos) +{ + /* + * ((DTLB_STORE_MISSES.STLB_HIT * 7) + DTLB_STORE_MISSES.WALK_DURATION) / + * CPU_CLK_UNHALTED.THREAD_P (t >= .1) + */ + int ret; + struct counters *dtsb_m, *dtsb_d; + struct counters *unhalt; + double con, un, d1, d2, res; + + con = 7.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + dtsb_m = find_counter(cpu, "DTLB_STORE_MISSES.STLB_HIT"); + dtsb_d = find_counter(cpu, "DTLB_STORE_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = dtsb_m->vals[pos] * 1.0; + d2 = dtsb_d->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = dtsb_m->sum * 1.0; + d2 = dtsb_d->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((d1 * con) + d2)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +itlb_miss(struct counters *cpu, int pos) +{ + /* ITLB_MISSES.WALK_DURATION / CPU_CLK_UNTHREAD_P IB */ + int ret; + struct counters *itlb; + struct counters *unhalt; + double un, d1, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION"); + if (pos != -1) { + d1 = itlb->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = itlb->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = d1/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +icache_miss(struct counters *cpu, int pos) +{ + /* (ICACHE.IFETCH_STALL - ITLB_MISSES.WALK_DURATION) / CPU_CLK_UNHALTED.THREAD_P IB */ + + int ret; + struct counters *itlb, *icache; + struct counters *unhalt; + double un, d1, ic, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + itlb = find_counter(cpu, "ITLB_MISSES.WALK_DURATION"); + icache = find_counter(cpu, "ICACHE.IFETCH_STALL"); + if (pos != -1) { + d1 = itlb->vals[pos] * 1.0; + ic = icache->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = itlb->sum * 1.0; + ic = icache->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ic-d1)/un; + ret = printf("%1.3f", res); + return(ret); + +} + +static int +icache_miss_has(struct counters *cpu, int pos) +{ + /* (36 * ICACHE.MISSES) / CPU_CLK_UNHALTED.THREAD_P */ + + int ret; + struct counters *icache; + struct counters *unhalt; + double un, con, ic, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + icache = find_counter(cpu, "ICACHE.MISSES"); + con = 36.0; + if (pos != -1) { + ic = icache->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ic = icache->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (con * ic)/un; + ret = printf("%1.3f", res); + return(ret); + +} + +static int +lcp_stall(struct counters *cpu, int pos) +{ + /* ILD_STALL.LCP/CPU_CLK_UNHALTED.THREAD_P IB */ + int ret; + struct counters *ild; + struct counters *unhalt; + double un, d1, res; + + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ild = find_counter(cpu, "ILD_STALL.LCP"); + if (pos != -1) { + d1 = ild->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + d1 = ild->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = d1/un; + ret = printf("%1.3f", res); + return(ret); + +} + + +static int +frontendstall(struct counters *cpu, int pos) +{ + /* 12 - IDQ_UOPS_NOT_DELIVERED.CORE / (CPU_CLK_UNHALTED.THREAD_P * 4) (thresh >= .15) */ + int ret; + struct counters *idq; + struct counters *unhalt; + double con, un, id, res; + + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + idq = find_counter(cpu, "IDQ_UOPS_NOT_DELIVERED.CORE"); + if (pos != -1) { + id = idq->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + id = idq->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = id/(un * con); + ret = printf("%1.3f", res); + return(ret); +} + +static int +clears(struct counters *cpu, int pos) +{ + /* 13 - ((MACHINE_CLEARS.MEMORY_ORDERING + MACHINE_CLEARS.SMC + MACHINE_CLEARS.MASKMOV ) * 100 ) + * / CPU_CLK_UNHALTED.THREAD_P (thresh >= .02)*/ + + int ret; + struct counters *clr1, *clr2, *clr3; + struct counters *unhalt; + double con, un, cl1, cl2, cl3, res; + + con = 100.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + clr1 = find_counter(cpu, "MACHINE_CLEARS.MEMORY_ORDERING"); + clr2 = find_counter(cpu, "MACHINE_CLEARS.SMC"); + clr3 = find_counter(cpu, "MACHINE_CLEARS.MASKMOV"); + + if (pos != -1) { + cl1 = clr1->vals[pos] * 1.0; + cl2 = clr2->vals[pos] * 1.0; + cl3 = clr3->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + cl1 = clr1->sum * 1.0; + cl2 = clr2->sum * 1.0; + cl3 = clr3->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ((cl1 + cl2 + cl3) * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +microassist(struct counters *cpu, int pos) +{ + /* 14 - IDQ.MS_CYCLES / CPU_CLK_UNHALTED.THREAD_P (thresh > .05) */ + int ret; + struct counters *idq; + struct counters *unhalt; + double un, id, res, con; + + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + idq = find_counter(cpu, "IDQ.MS_UOPS"); + if (pos != -1) { + id = idq->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + id = idq->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = id/(un * con); + ret = printf("%1.3f", res); + return(ret); +} + + +static int +aliasing(struct counters *cpu, int pos) +{ + /* 15 - (LD_BLOCKS_PARTIAL.ADDRESS_ALIAS * 5) / CPU_CLK_UNHALTED.THREAD_P (thresh > .1) */ + int ret; + struct counters *ld; + struct counters *unhalt; + double un, lds, con, res; + + con = 5.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + ld = find_counter(cpu, "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS"); + if (pos != -1) { + lds = ld->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + lds = ld->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (lds * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +fpassists(struct counters *cpu, int pos) +{ + /* 16 - FP_ASSIST.ANY/INST_RETIRED.ANY_P */ + int ret; + struct counters *fp; + struct counters *inst; + double un, fpd, res; + + inst = find_counter(cpu, "INST_RETIRED.ANY_P"); + fp = find_counter(cpu, "FP_ASSIST.ANY"); + if (pos != -1) { + fpd = fp->vals[pos] * 1.0; + un = inst->vals[pos] * 1.0; + } else { + fpd = fp->sum * 1.0; + un = inst->sum * 1.0; + } + res = fpd/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +otherassistavx(struct counters *cpu, int pos) +{ + /* 17 - (OTHER_ASSISTS.AVX_TO_SSE * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/ + int ret; + struct counters *oth; + struct counters *unhalt; + double un, ot, con, res; + + con = 75.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + oth = find_counter(cpu, "OTHER_ASSISTS.AVX_TO_SSE"); + if (pos != -1) { + ot = oth->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = oth->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ot * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +otherassistsse(struct counters *cpu, int pos) +{ + + int ret; + struct counters *oth; + struct counters *unhalt; + double un, ot, con, res; + + /* 18 (OTHER_ASSISTS.SSE_TO_AVX * 75)/CPU_CLK_UNHALTED.THREAD_P thresh .1*/ + con = 75.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + oth = find_counter(cpu, "OTHER_ASSISTS.SSE_TO_AVX"); + if (pos != -1) { + ot = oth->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = oth->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = (ot * con)/un; + ret = printf("%1.3f", res); + return(ret); +} + +static int +efficiency1(struct counters *cpu, int pos) +{ + + int ret; + struct counters *uops; + struct counters *unhalt; + double un, ot, con, res; + + /* 19 (UOPS_RETIRED.RETIRE_SLOTS/(4*CPU_CLK_UNHALTED.THREAD_P) look if thresh < .9*/ + con = 4.0; + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + uops = find_counter(cpu, "UOPS_RETIRED.RETIRE_SLOTS"); + if (pos != -1) { + ot = uops->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = uops->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = ot/(con * un); + ret = printf("%1.3f", res); + return(ret); +} + +static int +efficiency2(struct counters *cpu, int pos) +{ + + int ret; + struct counters *uops; + struct counters *unhalt; + double un, ot, res; + + /* 20 - CPU_CLK_UNHALTED.THREAD_P/INST_RETIRED.ANY_P good if > 1. (comp factor)*/ + unhalt = find_counter(cpu, "CPU_CLK_UNHALTED.THREAD_P"); + uops = find_counter(cpu, "INST_RETIRED.ANY_P"); + if (pos != -1) { + ot = uops->vals[pos] * 1.0; + un = unhalt->vals[pos] * 1.0; + } else { + ot = uops->sum * 1.0; + un = unhalt->sum * 1.0; + } + res = un/ot; + ret = printf("%1.3f", res); + return(ret); +} + +#define SANDY_BRIDGE_COUNT 20 +static struct cpu_entry sandy_bridge[SANDY_BRIDGE_COUNT] = { +/*01*/ { "allocstall1", "thresh > .05", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.SLOW_LEA_WINDOW -w 1", + allocstall1 }, +/*02*/ { "allocstall2", "thresh > .05", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s PARTIAL_RAT_STALLS.FLAGS_MERGE_UOP_CYCLES -w 1", + allocstall2 }, +/*03*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1", + br_mispredict }, +/*04*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1", + splitload }, +/*05*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*06*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested }, +/*07*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*08*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2 }, +/*09*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1 }, +/*10*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*11*/ { "dtlbmissstore", "thresh >= .05", + "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missstore }, +/*12*/ { "frontendstall", "thresh >= .15", + "pmcstat -s IDQ_UOPS_NOT_DELIVERED.CORE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + frontendstall }, +/*13*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*14*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*15*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*16*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*17*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*18*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +/*19*/ { "eff1", "thresh < .9", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*20*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +}; + + +#define IVY_BRIDGE_COUNT 21 +static struct cpu_entry ivy_bridge[IVY_BRIDGE_COUNT] = { +/*1*/ { "eff1", "thresh < .75", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*2*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +/*3*/ { "itlbmiss", "thresh > .05", + "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + itlb_miss }, +/*4*/ { "icachemiss", "thresh > .05", + "pmcstat -s ICACHE.IFETCH_STALL -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + icache_miss }, +/*5*/ { "lcpstall", "thresh > .05", + "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1", + lcp_stall }, +/*6*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1ib }, +/*7*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2ib }, +/*8*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested }, +/*9*/ { "datashare", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + datasharing }, +/*10*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*11*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s L1D_PEND_MISS.PENDING -s MEM_LOAD_UOPS_RETIRED.L1_MISS -s LD_BLOCKS.NO_SR -w 1", + splitloadib }, +/*12*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*13*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*14*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*15*/ { "dtlbmissstore", "thresh >= .05", + "pmcstat -s DTLB_STORE_MISSES.STLB_HIT -s DTLB_STORE_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missstore }, +/*16*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s UOPS_ISSUED.ANY -s UOPS_RETIRED.RETIRE_SLOTS -s INT_MISC.RECOVERY_CYCLES -w 1", + br_mispredictib }, +/*17*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*18*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*19*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*20*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*21*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +}; + +#define HASWELL_COUNT 20 +static struct cpu_entry haswell[HASWELL_COUNT] = { +/*1*/ { "eff1", "thresh < .75", + "pmcstat -s UOPS_RETIRED.RETIRE_SLOTS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency1 }, +/*2*/ { "eff2", "thresh > 1.0", + "pmcstat -s INST_RETIRED.ANY_P -s CPU_CLK_UNHALTED.THREAD_P -w 1", + efficiency2 }, +/*3*/ { "itlbmiss", "thresh > .05", + "pmcstat -s ITLB_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + itlb_miss }, +/*4*/ { "icachemiss", "thresh > .05", + "pmcstat -s ICACHE.MISSES --s CPU_CLK_UNHALTED.THREAD_P -w 1", + icache_miss_has }, +/*5*/ { "lcpstall", "thresh > .05", + "pmcstat -s ILD_STALL.LCP -s CPU_CLK_UNHALTED.THREAD_P -w 1", + lcp_stall }, +/*6*/ { "cache1", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache1ib }, +/*7*/ { "cache2", "thresh >= .2", + "pmcstat -s MEM_LOAD_UOPS_RETIRED.LLC_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + cache2has }, +/*8*/ { "contested", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM -s CPU_CLK_UNHALTED.THREAD_P -w 1", + contested_has }, +/*9*/ { "datashare", "thresh >= .05", + "pmcstat -s MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT -s CPU_CLK_UNHALTED.THREAD_P -w 1", + datasharing_has }, +/*10*/ { "blockstorefwd", "thresh >= .05", + "pmcstat -s LD_BLOCKS_STORE_FORWARD -s CPU_CLK_UNHALTED.THREAD_P -w 1", + blockstoreforward }, +/*11*/ { "splitload", "thresh >= .1", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s MEM_UOP_RETIRED.SPLIT_LOADS -w 1", + splitload }, +/*12*/ { "splitstore", "thresh >= .01", + "pmcstat -s MEM_UOP_RETIRED.SPLIT_STORES -s MEM_UOP_RETIRED.ALL_STORES -w 1", + splitstore }, +/*13*/ { "aliasing_4k", "thresh >= .1", + "pmcstat -s LD_BLOCKS_PARTIAL.ADDRESS_ALIAS -s CPU_CLK_UNHALTED.THREAD_P -w 1", + aliasing }, +/*14*/ { "dtlbmissload", "thresh >= .1", + "pmcstat -s DTLB_LOAD_MISSES.STLB_HIT -s DTLB_LOAD_MISSES.WALK_DURATION -s CPU_CLK_UNHALTED.THREAD_P -w 1", + dtlb_missload }, +/*15*/ { "br_miss", "thresh >= .2", + "pmcstat -s CPU_CLK_UNHALTED.THREAD_P -s BR_MISP_RETIRED.ALL_BRANCHES -w 1", + br_mispredict }, +/*16*/ { "clears", "thresh >= .02", + "pmcstat -s MACHINE_CLEARS.MEMORY_ORDERING -s MACHINE_CLEARS.SMC -s MACHINE_CLEARS.MASKMOV -s CPU_CLK_UNHALTED.THREAD_P -w 1", + clears }, +/*17*/ { "microassist", "thresh >= .05", + "pmcstat -s IDQ.MS_UOPS,cmask=1 -s CPU_CLK_UNHALTED.THREAD_P -w 1", + microassist }, +/*18*/ { "fpassist", "look for a excessive value", + "pmcstat -s FP_ASSIST.ANY -s INST_RETIRED.ANY_P -w 1", + fpassists }, +/*19*/ { "otherassistavx", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.AVX_TO_SSE -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistavx }, +/*20*/ { "otherassistsse", "look for a excessive value", + "pmcstat -s OTHER_ASSISTS.SSE_TO_AVX -s CPU_CLK_UNHALTED.THREAD_P -w 1", + otherassistsse }, +}; + + +static void +set_sandybridge(void) +{ + strcpy(the_cpu.cputype, "SandyBridge PMC"); + the_cpu.number = SANDY_BRIDGE_COUNT; + the_cpu.ents = sandy_bridge; + the_cpu.explain = explain_name_sb; +} + +static void +set_ivybridge(void) +{ + strcpy(the_cpu.cputype, "IvyBridge PMC"); + the_cpu.number = IVY_BRIDGE_COUNT; + the_cpu.ents = ivy_bridge; + the_cpu.explain = explain_name_ib; +} + + +static void +set_haswell(void) +{ + strcpy(the_cpu.cputype, "HASWELL PMC"); + the_cpu.number = HASWELL_COUNT; + the_cpu.ents = haswell; + the_cpu.explain = explain_name_has; +} + +static void +set_expression(char *name) +{ + int found = 0, i; + for(i=0 ; i< the_cpu.number; i++) { + if (strcmp(name, the_cpu.ents[i].name) == 0) { + found = 1; + expression = the_cpu.ents[i].func; + command = the_cpu.ents[i].command; + threshold = the_cpu.ents[i].thresh; + break; + } + } + if (!found) { + printf("For CPU type %s we have no expression:%s\n", + the_cpu.cputype, name); + exit(-1); + } +} + + + + + +static int +validate_expression(char *name) +{ + int i, found; + + found = 0; + for(i=0 ; i< the_cpu.number; i++) { + if (strcmp(name, the_cpu.ents[i].name) == 0) { + found = 1; + break; + } + } + if (!found) { + return(-1); + } + return (0); +} + +static void +do_expression(struct counters *cpu, int pos) +{ + if (expression == NULL) + return; + (*expression)(cpu, pos); +} + +static void +process_header(int idx, char *p) +{ + struct counters *up; + int i, len, nlen; + /* + * Given header element idx, at p in + * form 's/NN/nameof' + * process the entry to pull out the name and + * the CPU number. + */ + if (strncmp(p, "s/", 2)) { + printf("Check -- invalid header no s/ in %s\n", + p); + return; + } + up = &cnts[idx]; + up->cpu = strtol(&p[2], NULL, 10); + len = strlen(p); + for (i=2; i<len; i++) { + if (p[i] == '/') { + nlen = strlen(&p[(i+1)]); + if (nlen < (MAX_NLEN-1)) { + strcpy(up->counter_name, &p[(i+1)]); + } else { + strncpy(up->counter_name, &p[(i+1)], (MAX_NLEN-1)); + } + } + } +} + +static void +build_counters_from_header(FILE *io) +{ + char buffer[8192], *p; + int i, len, cnt; + size_t mlen; + + /* We have a new start, lets + * setup our headers and cpus. + */ + if (fgets(buffer, sizeof(buffer), io) == NULL) { + printf("First line can't be read from file err:%d\n", errno); + return; + } + /* + * Ok output is an array of counters. Once + * we start to read the values in we must + * put them in there slot to match there CPU and + * counter being updated. We create a mass array + * of the counters, filling in the CPU and + * counter name. + */ + /* How many do we get? */ + len = strlen(buffer); + for (i=0, cnt=0; i<len; i++) { + if (strncmp(&buffer[i], "s/", 2) == 0) { + cnt++; + for(;i<len;i++) { + if (buffer[i] == ' ') + break; + } + } + } + mlen = sizeof(struct counters) * cnt; + cnts = malloc(mlen); + ncnts = cnt; + if (cnts == NULL) { + printf("No memory err:%d\n", errno); + return; + } + memset(cnts, 0, mlen); + for (i=0, cnt=0; i<len; i++) { + if (strncmp(&buffer[i], "s/", 2) == 0) { + p = &buffer[i]; + for(;i<len;i++) { + if (buffer[i] == ' ') { + buffer[i] = 0; + break; + } + } + process_header(cnt, p); + cnt++; + } + } + if (verbose) + printf("We have %d entries\n", cnt); +} +extern int max_to_collect; +int max_to_collect = MAX_COUNTER_SLOTS; + +static int +read_a_line(FILE *io) +{ + char buffer[8192], *p, *stop; + int pos, i; + + if (fgets(buffer, sizeof(buffer), io) == NULL) { + return(0); + } + p = buffer; + for (i=0; i<ncnts; i++) { + pos = cnts[i].pos; + cnts[i].vals[pos] = strtol(p, &stop, 0); + cnts[i].pos++; + cnts[i].sum += cnts[i].vals[pos]; + p = stop; + } + return (1); +} + +extern int cpu_count_out; +int cpu_count_out=0; + +static void +print_header(void) +{ + int i, cnt, printed_cnt; + + printf("*********************************\n"); + for(i=0, cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + cnt++; + } + } + cpu_count_out = cnt; + for(i=0, printed_cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + printf("CPU%d", i); + printed_cnt++; + } + if (printed_cnt == cnt) { + printf("\n"); + break; + } else { + printf("\t"); + } + } +} + +static void +lace_cpus_together(void) +{ + int i, j, lace_cpu; + struct counters *cpat, *at; + + for(i=0; i<ncnts; i++) { + cpat = &cnts[i]; + if (cpat->next_cpu) { + /* Already laced in */ + continue; + } + lace_cpu = cpat->cpu; + if (lace_cpu >= MAX_CPU) { + printf("CPU %d to big\n", lace_cpu); + continue; + } + if (glob_cpu[lace_cpu] == NULL) { + glob_cpu[lace_cpu] = cpat; + } else { + /* Already processed this cpu */ + continue; + } + /* Ok look forward for cpu->cpu and link in */ + for(j=(i+1); j<ncnts; j++) { + at = &cnts[j]; + if (at->next_cpu) { + continue; + } + if (at->cpu == lace_cpu) { + /* Found one */ + cpat->next_cpu = at; + cpat = at; + } + } + } +} + + +static void +process_file(char *filename) +{ + FILE *io; + int i; + int line_at, not_done; + pid_t pid_of_command=0; + + if (filename == NULL) { + io = my_popen(command, "r", &pid_of_command); + } else { + io = fopen(filename, "r"); + if (io == NULL) { + printf("Can't process file %s err:%d\n", + filename, errno); + return; + } + } + build_counters_from_header(io); + if (cnts == NULL) { + /* Nothing we can do */ + printf("Nothing to do -- no counters built\n"); + return; + } + lace_cpus_together(); + print_header(); + if (verbose) { + for (i=0; i<ncnts; i++) { + printf("Counter:%s cpu:%d index:%d\n", + cnts[i].counter_name, + cnts[i].cpu, i); + } + } + line_at = 0; + not_done = 1; + while(not_done) { + if (read_a_line(io)) { + line_at++; + } else { + break; + } + if (line_at >= max_to_collect) { + not_done = 0; + } + if (filename == NULL) { + int cnt; + /* For the ones we dynamically open we print now */ + for(i=0, cnt=0; i<MAX_CPU; i++) { + do_expression(glob_cpu[i], (line_at-1)); + cnt++; + if (cnt == cpu_count_out) { + printf("\n"); + break; + } else { + printf("\t"); + } + } + } + } + if (filename) { + fclose(io); + } else { + my_pclose(io, pid_of_command); + } +} +#if defined(__amd64__) +#define cpuid(in,a,b,c,d)\ + asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); +#else +#define cpuid(in, a, b, c, d) +#endif + +static void +get_cpuid_set(void) +{ + unsigned long eax, ebx, ecx, edx; + int model; + pid_t pid_of_command=0; + size_t sz, len; + FILE *io; + char linebuf[1024], *str; + + eax = ebx = ecx = edx = 0; + + cpuid(0, eax, ebx, ecx, edx); + if (ebx == 0x68747541) { + printf("AMD processors are not supported by this program\n"); + printf("Sorry\n"); + exit(0); + } else if (ebx == 0x6972794) { + printf("Cyrix processors are not supported by this program\n"); + printf("Sorry\n"); + exit(0); + } else if (ebx == 0x756e6547) { + printf("Genuine Intel\n"); + } else { + printf("Unknown processor type 0x%lx Only Intel AMD64 types are supported by this routine!\n", ebx); + exit(0); + } + cpuid(1, eax, ebx, ecx, edx); + model = (((eax & 0xF0000) >> 12) | ((eax & 0xF0) >> 4)); + printf("CPU model is 0x%x id:0x%lx\n", model, eax); + switch (eax & 0xF00) { + case 0x500: /* Pentium family processors */ + printf("Intel Pentium P5\n"); + goto not_supported; + break; + case 0x600: /* Pentium Pro, Celeron, Pentium II & III */ + switch (model) { + case 0x1: + printf("Intel Pentium P6\n"); + goto not_supported; + break; + case 0x3: + case 0x5: + printf("Intel PII\n"); + goto not_supported; + break; + case 0x6: case 0x16: + printf("Intel CL\n"); + goto not_supported; + break; + case 0x7: case 0x8: case 0xA: case 0xB: + printf("Intel PIII\n"); + goto not_supported; + break; + case 0x9: case 0xD: + printf("Intel PM\n"); + goto not_supported; + break; + case 0xE: + printf("Intel CORE\n"); + goto not_supported; + break; + case 0xF: + printf("Intel CORE2\n"); + goto not_supported; + break; + case 0x17: + printf("Intel CORE2EXTREME\n"); + goto not_supported; + break; + case 0x1C: /* Per Intel document 320047-002. */ + printf("Intel ATOM\n"); + goto not_supported; + break; + case 0x1A: + case 0x1E: /* + * Per Intel document 253669-032 9/2009, + * pages A-2 and A-57 + */ + case 0x1F: /* + * Per Intel document 253669-032 9/2009, + * pages A-2 and A-57 + */ + printf("Intel COREI7\n"); + goto not_supported; + break; + case 0x2E: + printf("Intel NEHALEM\n"); + goto not_supported; + break; + case 0x25: /* Per Intel document 253669-033US 12/2009. */ + case 0x2C: /* Per Intel document 253669-033US 12/2009. */ + printf("Intel WESTMERE\n"); + goto not_supported; + break; + case 0x2F: /* Westmere-EX, seen in wild */ + printf("Intel WESTMERE\n"); + goto not_supported; + break; + case 0x2A: /* Per Intel document 253669-039US 05/2011. */ + printf("Intel SANDYBRIDGE\n"); + set_sandybridge(); + break; + case 0x2D: /* Per Intel document 253669-044US 08/2012. */ + printf("Intel SANDYBRIDGE_XEON\n"); + set_sandybridge(); + break; + case 0x3A: /* Per Intel document 253669-043US 05/2012. */ + printf("Intel IVYBRIDGE\n"); + set_ivybridge(); + break; + case 0x3E: /* Per Intel document 325462-045US 01/2013. */ + printf("Intel IVYBRIDGE_XEON\n"); + set_ivybridge(); + break; + case 0x3F: /* Per Intel document 325462-045US 09/2014. */ + printf("Intel HASWELL (Xeon)\n"); + set_haswell(); + break; + case 0x3C: /* Per Intel document 325462-045US 01/2013. */ + case 0x45: + case 0x46: + printf("Intel HASWELL\n"); + set_haswell(); + break; + case 0x4D: + /* Per Intel document 330061-001 01/2014. */ + printf("Intel ATOM_SILVERMONT\n"); + goto not_supported; + break; + default: + printf("Intel model 0x%x is not known -- sorry\n", + model); + goto not_supported; + break; + } + break; + case 0xF00: /* P4 */ + printf("Intel unknown model %d\n", model); + goto not_supported; + break; + } + /* Ok lets load the list of all known PMC's */ + io = my_popen("/usr/sbin/pmccontrol -L", "r", &pid_of_command); + if (valid_pmcs == NULL) { + /* Likely */ + pmc_allocated_cnt = PMC_INITIAL_ALLOC; + sz = sizeof(char *) * pmc_allocated_cnt; + valid_pmcs = malloc(sz); + if (valid_pmcs == NULL) { + printf("No memory allocation fails at startup?\n"); + exit(-1); + } + memset(valid_pmcs, 0, sz); + } + + while (fgets(linebuf, sizeof(linebuf), io) != NULL) { + if (linebuf[0] != '\t') { + /* sometimes headers ;-) */ + continue; + } + len = strlen(linebuf); + if (linebuf[(len-1)] == '\n') { + /* Likely */ + linebuf[(len-1)] = 0; + } + str = &linebuf[1]; + len = strlen(str) + 1; + valid_pmcs[valid_pmc_cnt] = malloc(len); + if (valid_pmcs[valid_pmc_cnt] == NULL) { + printf("No memory2 allocation fails at startup?\n"); + exit(-1); + } + memset(valid_pmcs[valid_pmc_cnt], 0, len); + strcpy(valid_pmcs[valid_pmc_cnt], str); + valid_pmc_cnt++; + if (valid_pmc_cnt >= pmc_allocated_cnt) { + /* Got to expand -- unlikely */ + char **more; + + sz = sizeof(char *) * (pmc_allocated_cnt * 2); + more = malloc(sz); + if (more == NULL) { + printf("No memory3 allocation fails at startup?\n"); + exit(-1); + } + memset(more, sz, 0); + memcpy(more, valid_pmcs, sz); + pmc_allocated_cnt *= 2; + free(valid_pmcs); + valid_pmcs = more; + } + } + my_pclose(io, pid_of_command); + return; +not_supported: + printf("Not supported\n"); + exit(-1); +} + +static void +explain_all(void) +{ + int i; + printf("For CPU's of type %s the following expressions are available:\n",the_cpu.cputype); + printf("-------------------------------------------------------------\n"); + for(i=0; i<the_cpu.number; i++){ + printf("For -e %s ", the_cpu.ents[i].name); + (*the_cpu.explain)(the_cpu.ents[i].name); + printf("----------------------------\n"); + } +} + +static void +test_for_a_pmc(const char *pmc, int out_so_far) +{ + FILE *io; + pid_t pid_of_command=0; + char my_command[1024]; + char line[1024]; + char resp[1024]; + int len, llen, i; + + if (out_so_far < 50) { + len = 50 - out_so_far; + for(i=0; i<len; i++) { + printf(" "); + } + } + sprintf(my_command, "/usr/sbin/pmcstat -w .25 -c 0 -s %s", pmc); + io = my_popen(my_command, "r", &pid_of_command); + if (io == NULL) { + printf("Failed -- popen fails\n"); + return; + } + /* Setup what we expect */ + len = sprintf(resp, "%s", pmc); + if (fgets(line, sizeof(line), io) == NULL) { + printf("Failed -- no output from pmstat\n"); + goto out; + } + llen = strlen(line); + if (line[(llen-1)] == '\n') { + line[(llen-1)] = 0; + llen--; + } + for(i=2; i<(llen-len); i++) { + if (strncmp(&line[i], "ERROR", 5) == 0) { + printf("Failed %s\n", line); + goto out; + } else if (strncmp(&line[i], resp, len) == 0) { + int j, k; + + if (fgets(line, sizeof(line), io) == NULL) { + printf("Failed -- no second output from pmstat\n"); + goto out; + } + len = strlen(line); + for (j=0; j<len; j++) { + if (line[j] == ' ') { + j++; + } else { + break; + } + } + printf("Pass"); + len = strlen(&line[j]); + if (len < 20) { + for(k=0; k<(20-len); k++) { + printf(" "); + } + } + printf("%s", &line[j]); + goto out; + } + } + printf("Failed -- '%s' not '%s'\n", line, resp); +out: + my_pclose(io, pid_of_command); + +} + +static int +add_it_to(char **vars, int cur_cnt, char *name) +{ + int i; + size_t len; + for(i=0; i<cur_cnt; i++) { + if (strcmp(vars[i], name) == 0) { + /* Already have */ + return(0); + } + } + if (vars[cur_cnt] != NULL) { + printf("Cur_cnt:%d filled with %s??\n", + cur_cnt, vars[cur_cnt]); + exit(-1); + } + /* Ok its new */ + len = strlen(name) + 1; + vars[cur_cnt] = malloc(len); + if (vars[cur_cnt] == NULL) { + printf("No memory %s\n", __FUNCTION__); + exit(-1); + } + memset(vars[cur_cnt], 0, len); + strcpy(vars[cur_cnt], name); + return(1); +} + +static char * +build_command_for_exp(struct expression *exp) +{ + /* + * Build the pmcstat command to handle + * the passed in expression. + * /usr/sbin/pmcstat -w 1 -s NNN -s QQQ + * where NNN and QQQ represent the PMC's in the expression + * uniquely.. + */ + char forming[1024]; + int cnt_pmc, alloced_pmcs, i; + struct expression *at; + char **vars, *cmd; + size_t mal; + + alloced_pmcs = cnt_pmc = 0; + /* first how many do we have */ + at = exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + cnt_pmc++; + } + at = at->next; + } + if (cnt_pmc == 0) { + printf("No PMC's in your expression -- nothing to do!!\n"); + exit(0); + } + mal = cnt_pmc * sizeof(char *); + vars = malloc(mal); + if (vars == NULL) { + printf("No memory\n"); + exit(-1); + } + memset(vars, 0, mal); + at = exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + if(add_it_to(vars, alloced_pmcs, at->name)) { + alloced_pmcs++; + } + } + at = at->next; + } + /* Now we have a unique list in vars so create our command */ + mal = 23; /* "/usr/sbin/pmcstat -w 1" + \0 */ + for(i=0; i<alloced_pmcs; i++) { + mal += strlen(vars[i]) + 4; /* var + " -s " */ + } + cmd = malloc((mal+2)); + if (cmd == NULL) { + printf("%s out of mem\n", __FUNCTION__); + exit(-1); + } + memset(cmd, 0, (mal+2)); + strcpy(cmd, "/usr/sbin/pmcstat -w 1"); + at = exp; + for(i=0; i<alloced_pmcs; i++) { + sprintf(forming, " -s %s", vars[i]); + strcat(cmd, forming); + free(vars[i]); + vars[i] = NULL; + } + free(vars); + return(cmd); +} + +static int +user_expr(struct counters *cpu, int pos) +{ + int ret; + double res; + struct counters *var; + struct expression *at; + + at = master_exp; + while (at) { + if (at->type == TYPE_VALUE_PMC) { + var = find_counter(cpu, at->name); + if (var == NULL) { + printf("%s:Can't find counter %s?\n", __FUNCTION__, at->name); + exit(-1); + } + if (pos != -1) { + at->value = var->vals[pos] * 1.0; + } else { + at->value = var->sum * 1.0; + } + } + at = at->next; + } + res = run_expr(master_exp, 1, NULL); + ret = printf("%1.3f", res); + return(ret); +} + + +static void +set_manual_exp(struct expression *exp) +{ + expression = user_expr; + command = build_command_for_exp(exp); + threshold = "User defined threshold"; +} + +static void +run_tests(void) +{ + int i, lenout; + printf("Running tests on %d PMC's this may take some time\n", valid_pmc_cnt); + printf("------------------------------------------------------------------------\n"); + for(i=0; i<valid_pmc_cnt; i++) { + lenout = printf("%s", valid_pmcs[i]); + fflush(stdout); + test_for_a_pmc(valid_pmcs[i], lenout); + } +} +static void +list_all(void) +{ + int i, cnt, j; + printf("PMC Abbreviation\n"); + printf("--------------------------------------------------------------\n"); + for(i=0; i<valid_pmc_cnt; i++) { + cnt = printf("%s", valid_pmcs[i]); + for(j=cnt; j<52; j++) { + printf(" "); + } + printf("%%%d\n", i); + } +} + + +int +main(int argc, char **argv) +{ + int i, j, cnt; + char *filename=NULL; + char *name=NULL; + int help_only = 0; + int test_mode = 0; + + get_cpuid_set(); + memset(glob_cpu, 0, sizeof(glob_cpu)); + while ((i = getopt(argc, argv, "LHhvm:i:?e:TE:")) != -1) { + switch (i) { + case 'L': + list_all(); + return(0); + case 'H': + printf("**********************************\n"); + explain_all(); + printf("**********************************\n"); + return(0); + break; + case 'T': + test_mode = 1; + break; + case 'E': + master_exp = parse_expression(optarg); + if (master_exp) { + set_manual_exp(master_exp); + } + break; + case 'e': + if (validate_expression(optarg)) { + printf("Unknown expression %s\n", optarg); + return(0); + } + name = optarg; + set_expression(optarg); + break; + case 'm': + max_to_collect = strtol(optarg, NULL, 0); + if (max_to_collect > MAX_COUNTER_SLOTS) { + /* You can't collect more than max in array */ + max_to_collect = MAX_COUNTER_SLOTS; + } + break; + case 'v': + verbose++; + break; + case 'h': + help_only = 1; + break; + case 'i': + filename = optarg; + break; + case '?': + default: + use: + printf("Use %s [ -i inputfile -v -m max_to_collect -e expr -E -h -? -H]\n", + argv[0]); + printf("-i inputfile -- use source as inputfile not stdin (if stdin collect)\n"); + printf("-v -- verbose dump debug type things -- you don't want this\n"); + printf("-m N -- maximum to collect is N measurments\n"); + printf("-e expr-name -- Do expression expr-name\n"); + printf("-E 'your expression' -- Do your expression\n"); + printf("-h -- Don't do the expression I put in -e xxx just explain what it does and exit\n"); + printf("-H -- Don't run anything, just explain all canned expressions\n"); + printf("-T -- Test all PMC's defined by this processor\n"); + return(0); + break; + }; + } + if ((name == NULL) && (filename == NULL) && (test_mode == 0) && (master_exp == NULL)) { + printf("Without setting an expression we cannot dynamically gather information\n"); + printf("you must supply a filename (and you probably want verbosity)\n"); + goto use; + } + if (test_mode) { + run_tests(); + return(0); + } + printf("*********************************\n"); + if (master_exp == NULL) { + (*the_cpu.explain)(name); + } else { + printf("Examine your expression "); + print_exp(master_exp); + printf("User defined threshold\n"); + } + if (help_only) { + return(0); + } + process_file(filename); + if (verbose >= 2) { + for (i=0; i<ncnts; i++) { + printf("Counter:%s cpu:%d index:%d\n", + cnts[i].counter_name, + cnts[i].cpu, i); + for(j=0; j<cnts[i].pos; j++) { + printf(" val - %ld\n", (long int)cnts[i].vals[j]); + } + printf(" sum - %ld\n", (long int)cnts[i].sum); + } + } + if (expression == NULL) { + return(0); + } + for(i=0, cnt=0; i<MAX_CPU; i++) { + if (glob_cpu[i]) { + do_expression(glob_cpu[i], -1); + cnt++; + if (cnt == cpu_count_out) { + printf("\n"); + break; + } else { + printf("\t"); + } + } + } + return(0); +} |