aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2012-08-06 01:11:22 -0400
committerThomas Gleixner <tglx@linutronix.de>2012-08-13 13:01:04 -0400
commitcb37af77124e8532e6ae3f9ca332593ba423b5f8 (patch)
treeda6d33dfaf0ce299193a2e32f3ce218156fe33ba /arch
parentebb6cc03596cc89c89670473282ea46573feb34f (diff)
perf/x86: Add Intel Westmere-EX uncore support
The Westmere-EX uncore is similar to the Nehalem-EX uncore. The differences are: - Westmere-EX uncore has 10 instances of Cbox. The MSRs for Cbox8 and Cbox9 in the Westmere-EX aren't contiguous with Cbox 0~7. - The fvid field in the ZDP_CTL_FVC register in the Mbox is different. It's 5 bits in the Nehalem-EX, 6 bits in the Westmere-EX. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1344229882-3907-3-git-send-email-zheng.z.yan@intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c56
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h45
2 files changed, 68 insertions, 33 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index 84434e2a676f..0a5571080e74 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -901,16 +901,21 @@ static struct attribute_group nhmex_uncore_cbox_format_group = {
901 .attrs = nhmex_uncore_cbox_formats_attr, 901 .attrs = nhmex_uncore_cbox_formats_attr,
902}; 902};
903 903
904/* msr offset for each instance of cbox */
905static unsigned nhmex_cbox_msr_offsets[] = {
906 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0,
907};
908
904static struct intel_uncore_type nhmex_uncore_cbox = { 909static struct intel_uncore_type nhmex_uncore_cbox = {
905 .name = "cbox", 910 .name = "cbox",
906 .num_counters = 6, 911 .num_counters = 6,
907 .num_boxes = 8, 912 .num_boxes = 10,
908 .perf_ctr_bits = 48, 913 .perf_ctr_bits = 48,
909 .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, 914 .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0,
910 .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, 915 .perf_ctr = NHMEX_C0_MSR_PMON_CTR0,
911 .event_mask = NHMEX_PMON_RAW_EVENT_MASK, 916 .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
912 .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, 917 .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
913 .msr_offset = NHMEX_C_MSR_OFFSET, 918 .msr_offsets = nhmex_cbox_msr_offsets,
914 .pair_ctr_ctl = 1, 919 .pair_ctr_ctl = 1,
915 .ops = &nhmex_uncore_ops, 920 .ops = &nhmex_uncore_ops,
916 .format_group = &nhmex_uncore_cbox_format_group 921 .format_group = &nhmex_uncore_cbox_format_group
@@ -1138,6 +1143,9 @@ static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
1138 EVENT_EXTRA_END 1143 EVENT_EXTRA_END
1139}; 1144};
1140 1145
1146/* Nehalem-EX or Westmere-EX ? */
1147bool uncore_nhmex;
1148
1141static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) 1149static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
1142{ 1150{
1143 struct intel_uncore_extra_reg *er; 1151 struct intel_uncore_extra_reg *er;
@@ -1167,18 +1175,29 @@ static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64
1167 return false; 1175 return false;
1168 1176
1169 /* mask of the shared fields */ 1177 /* mask of the shared fields */
1170 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; 1178 if (uncore_nhmex)
1179 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
1180 else
1181 mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK;
1171 er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; 1182 er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
1172 1183
1173 raw_spin_lock_irqsave(&er->lock, flags); 1184 raw_spin_lock_irqsave(&er->lock, flags);
1174 /* add mask of the non-shared field if it's in use */ 1185 /* add mask of the non-shared field if it's in use */
1175 if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) 1186 if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) {
1176 mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); 1187 if (uncore_nhmex)
1188 mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1189 else
1190 mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1191 }
1177 1192
1178 if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { 1193 if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
1179 atomic_add(1 << (idx * 8), &er->ref); 1194 atomic_add(1 << (idx * 8), &er->ref);
1180 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | 1195 if (uncore_nhmex)
1181 NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); 1196 mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
1197 NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1198 else
1199 mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK |
1200 WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1182 er->config &= ~mask; 1201 er->config &= ~mask;
1183 er->config |= (config & mask); 1202 er->config |= (config & mask);
1184 ret = true; 1203 ret = true;
@@ -1212,7 +1231,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
1212 1231
1213 /* get the non-shared control bits and shift them */ 1232 /* get the non-shared control bits and shift them */
1214 idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; 1233 idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
1215 config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); 1234 if (uncore_nhmex)
1235 config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1236 else
1237 config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
1216 if (new_idx > orig_idx) { 1238 if (new_idx > orig_idx) {
1217 idx = new_idx - orig_idx; 1239 idx = new_idx - orig_idx;
1218 config <<= 3 * idx; 1240 config <<= 3 * idx;
@@ -1222,6 +1244,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
1222 } 1244 }
1223 1245
1224 /* add the shared control bits back */ 1246 /* add the shared control bits back */
1247 if (uncore_nhmex)
1248 config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
1249 else
1250 config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
1225 config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; 1251 config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
1226 if (modify) { 1252 if (modify) {
1227 /* adjust the main event selector */ 1253 /* adjust the main event selector */
@@ -1480,6 +1506,12 @@ static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
1480 { /* end: all zeroes */ }, 1506 { /* end: all zeroes */ },
1481}; 1507};
1482 1508
1509static struct uncore_event_desc wsmex_uncore_mbox_events[] = {
1510 INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"),
1511 INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"),
1512 { /* end: all zeroes */ },
1513};
1514
1483static struct intel_uncore_ops nhmex_uncore_mbox_ops = { 1515static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
1484 NHMEX_UNCORE_OPS_COMMON_INIT(), 1516 NHMEX_UNCORE_OPS_COMMON_INIT(),
1485 .enable_event = nhmex_mbox_msr_enable_event, 1517 .enable_event = nhmex_mbox_msr_enable_event,
@@ -2791,7 +2823,13 @@ static int __init uncore_cpu_init(void)
2791 snbep_uncore_cbox.num_boxes = max_cores; 2823 snbep_uncore_cbox.num_boxes = max_cores;
2792 msr_uncores = snbep_msr_uncores; 2824 msr_uncores = snbep_msr_uncores;
2793 break; 2825 break;
2794 case 46: 2826 case 46: /* Nehalem-EX */
2827 uncore_nhmex = true;
2828 case 47: /* Westmere-EX aka. Xeon E7 */
2829 if (!uncore_nhmex)
2830 nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
2831 if (nhmex_uncore_cbox.num_boxes > max_cores)
2832 nhmex_uncore_cbox.num_boxes = max_cores;
2795 msr_uncores = nhmex_msr_uncores; 2833 msr_uncores = nhmex_msr_uncores;
2796 break; 2834 break;
2797 default: 2835 default:
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
index 8384e9b543b7..5b81c1856aac 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -276,18 +276,12 @@
276 NHMEX_M_PMON_CTL_INC_SEL_MASK | \ 276 NHMEX_M_PMON_CTL_INC_SEL_MASK | \
277 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) 277 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
278 278
279 279#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23))
280#define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f
281#define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5)
282#define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8)
283#define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23)
284#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \
285 (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \
286 NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \
287 NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \
288 NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR)
289#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) 280#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n)))
290 281
282#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24))
283#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (12 + 3 * (n)))
284
291/* 285/*
292 * use the 9~13 bits to select event If the 7th bit is not set, 286 * use the 9~13 bits to select event If the 7th bit is not set,
293 * otherwise use the 19~21 bits to select event. 287 * otherwise use the 19~21 bits to select event.
@@ -369,6 +363,7 @@ struct intel_uncore_type {
369 unsigned num_shared_regs:8; 363 unsigned num_shared_regs:8;
370 unsigned single_fixed:1; 364 unsigned single_fixed:1;
371 unsigned pair_ctr_ctl:1; 365 unsigned pair_ctr_ctl:1;
366 unsigned *msr_offsets;
372 struct event_constraint unconstrainted; 367 struct event_constraint unconstrainted;
373 struct event_constraint *constraints; 368 struct event_constraint *constraints;
374 struct intel_uncore_pmu *pmus; 369 struct intel_uncore_pmu *pmus;
@@ -486,29 +481,31 @@ unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
486 return idx * 8 + box->pmu->type->perf_ctr; 481 return idx * 8 + box->pmu->type->perf_ctr;
487} 482}
488 483
489static inline 484static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box)
490unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) 485{
486 struct intel_uncore_pmu *pmu = box->pmu;
487 return pmu->type->msr_offsets ?
488 pmu->type->msr_offsets[pmu->pmu_idx] :
489 pmu->type->msr_offset * pmu->pmu_idx;
490}
491
492static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
491{ 493{
492 if (!box->pmu->type->box_ctl) 494 if (!box->pmu->type->box_ctl)
493 return 0; 495 return 0;
494 return box->pmu->type->box_ctl + 496 return box->pmu->type->box_ctl + uncore_msr_box_offset(box);
495 box->pmu->type->msr_offset * box->pmu->pmu_idx;
496} 497}
497 498
498static inline 499static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
499unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
500{ 500{
501 if (!box->pmu->type->fixed_ctl) 501 if (!box->pmu->type->fixed_ctl)
502 return 0; 502 return 0;
503 return box->pmu->type->fixed_ctl + 503 return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box);
504 box->pmu->type->msr_offset * box->pmu->pmu_idx;
505} 504}
506 505
507static inline 506static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
508unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
509{ 507{
510 return box->pmu->type->fixed_ctr + 508 return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
511 box->pmu->type->msr_offset * box->pmu->pmu_idx;
512} 509}
513 510
514static inline 511static inline
@@ -516,7 +513,7 @@ unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
516{ 513{
517 return box->pmu->type->event_ctl + 514 return box->pmu->type->event_ctl +
518 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + 515 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
519 box->pmu->type->msr_offset * box->pmu->pmu_idx; 516 uncore_msr_box_offset(box);
520} 517}
521 518
522static inline 519static inline
@@ -524,7 +521,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
524{ 521{
525 return box->pmu->type->perf_ctr + 522 return box->pmu->type->perf_ctr +
526 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + 523 (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
527 box->pmu->type->msr_offset * box->pmu->pmu_idx; 524 uncore_msr_box_offset(box);
528} 525}
529 526
530static inline 527static inline