summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libpmc/libpmc.c25
-rw-r--r--sys/amd64/conf/GENERIC1
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c494
-rw-r--r--sys/dev/hwpmc/hwpmc_intel.c9
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c11
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c5
-rw-r--r--sys/dev/hwpmc/hwpmc_piv.c5
-rw-r--r--sys/dev/hwpmc/hwpmc_uncore.c4
-rw-r--r--sys/dev/hwpmc/hwpmc_x86.c4
-rw-r--r--sys/dev/hwpmc/pmc_events.h340
-rw-r--r--sys/sys/pmc.h1
-rw-r--r--usr.sbin/Makefile1
-rw-r--r--usr.sbin/pmcstudy/Makefile11
-rw-r--r--usr.sbin/pmcstudy/eval_expr.c717
-rw-r--r--usr.sbin/pmcstudy/eval_expr.h58
-rw-r--r--usr.sbin/pmcstudy/pmcstudy.165
-rw-r--r--usr.sbin/pmcstudy/pmcstudy.c2425
17 files changed, 3913 insertions, 263 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/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 03a0f9f..4a2df33 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -84,6 +84,7 @@ options SMP # Symmetric MultiProcessor Kernel
device cpufreq
# Bus support.
+device hwpmc
device acpi
options ACPI_DMAR
device pci
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index f182450..86e71d4 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 9fd02889..cb313c2 100644
--- a/sys/dev/hwpmc/hwpmc_intel.c
+++ b/sys/dev/hwpmc/hwpmc_intel.c
@@ -171,7 +171,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: /* Per Intel document 325462-045US 09/2014. */
cputype = PMC_CPU_INTEL_HASWELL;
nclasses = 5;
break;
@@ -224,6 +231,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);
break;
@@ -309,6 +317,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 c9b8aea..4d14011 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -37,7 +37,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#if (__FreeBSD_version >= 1100000)
#include <sys/capsicum.h>
+#else
+#include <sys/capability.h>
+#endif
#include <sys/file.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
@@ -66,8 +70,7 @@ SYSCTL_DECL(_kern_hwpmc);
*/
static int pmclog_buffer_size = PMC_LOG_BUFFER_SIZE;
-TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "logbuffersize", &pmclog_buffer_size);
-SYSCTL_INT(_kern_hwpmc, OID_AUTO, logbuffersize, CTLFLAG_TUN|CTLFLAG_RD,
+SYSCTL_INT(_kern_hwpmc, OID_AUTO, logbuffersize, CTLFLAG_RDTUN,
&pmclog_buffer_size, 0, "size of log buffers in kilobytes");
/*
@@ -75,8 +78,7 @@ SYSCTL_INT(_kern_hwpmc, OID_AUTO, logbuffersize, CTLFLAG_TUN|CTLFLAG_RD,
*/
static int pmc_nlogbuffers = PMC_NLOGBUFFERS;
-TUNABLE_INT(PMC_SYSCTL_NAME_PREFIX "nbuffers", &pmc_nlogbuffers);
-SYSCTL_INT(_kern_hwpmc, OID_AUTO, nbuffers, CTLFLAG_TUN|CTLFLAG_RD,
+SYSCTL_INT(_kern_hwpmc, OID_AUTO, nbuffers, CTLFLAG_RDTUN,
&pmc_nlogbuffers, 0, "number of global log buffers");
/*
@@ -571,7 +573,6 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd)
int error;
struct proc *p;
cap_rights_t rights;
-
/*
* 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
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 9eea4ba..98513b3 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -325,7 +325,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 7e3cb48..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 b931fcc..2895f2c 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 f4c6c94..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 0caf2dd..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,15 +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("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) \
@@ -2591,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) \
@@ -2707,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) \
@@ -2726,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) \
@@ -2746,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) \
@@ -2758,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,19 +3037,29 @@ __PMC_EV_ALIAS("L2_LINES_OUT.DEMAND_DIRTY", IAP_EVENT_F2H_06H)
#define __PMC_EV_ALIAS_IVYBRIDGE() \
__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) \
@@ -2849,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", \
@@ -2873,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) \
@@ -2913,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) \
@@ -2932,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) \
@@ -2964,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", \
@@ -2981,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) \
@@ -3003,19 +3269,29 @@ __PMC_EV_ALIAS("L2_LINES_OUT.PF_DIRTY", IAP_EVENT_F2H_08H)
*/
#define __PMC_EV_ALIAS_IVYBRIDGE_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.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) \
@@ -3080,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) \
@@ -3124,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) \
@@ -3143,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) \
@@ -3175,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", \
@@ -3191,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", \
@@ -3350,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) \
@@ -3583,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 d2e55e2..b501d1c 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -279,6 +279,7 @@ SUBDIR+= pkg_install
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);
+}
OpenPOWER on IntegriCloud