PAPI 7.1.0.0
Loading...
Searching...
No Matches
pfmlib_pentium4.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
3 * Copyright (c) 2006 IBM Corp.
4 * Contributed by Kevin Corry <kevcorry@us.ibm.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * pfmlib_pentium4.c
25 *
26 * Support for libpfm for the Pentium4/Xeon/EM64T processor family (family=15).
27 */
28
29#ifndef _GNU_SOURCE
30 #define _GNU_SOURCE /* for getline */
31#endif
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <limits.h>
37
38/* private headers */
39#include "pfmlib_priv.h"
41#include "pentium4_events.h"
42
43typedef struct {
44 unsigned long addr;
45 char *name;
47
48#define P4_REGMAP(a, n) { .addr = a, .name = n }
49
51/* 0 */ P4_REGMAP(0x3b2, "BPU_ESCR0"),
52/* 1 */ P4_REGMAP(0x3ba, "IS_ESCR0"),
53/* 2 */ P4_REGMAP(0x3aa, "MOB_ESCR0"),
54/* 3 */ P4_REGMAP(0x3b6, "ITLB_ESCR0"),
55/* 4 */ P4_REGMAP(0x3ac, "PMH_ESCR0"),
56/* 5 */ P4_REGMAP(0x3c8, "IX_ESCR0"),
57/* 6 */ P4_REGMAP(0x3a2, "FSB_ESCR0"),
58/* 7 */ P4_REGMAP(0x3a0, "BSU_ESCR0"),
59/* 8 */ P4_REGMAP(0x3c0, "MS_ESCR0"),
60/* 9 */ P4_REGMAP(0x3c4, "TC_ESCR0"),
61/* 10 */ P4_REGMAP(0x3c2, "TBPU_ESCR0"),
62/* 11 */ P4_REGMAP(0x3a6, "FLAME_ESCR0"),
63/* 12 */ P4_REGMAP(0x3a4, "FIRM_ESCR0"),
64/* 13 */ P4_REGMAP(0x3ae, "SAAT_ESCR0"),
65/* 14 */ P4_REGMAP(0x3b0, "U2L_ESCR0"),
66/* 15 */ P4_REGMAP(0x3a8, "DAC_ESCR0"),
67/* 16 */ P4_REGMAP(0x3ba, "IQ_ESCR0"),
68/* 17 */ P4_REGMAP(0x3ca, "ALF_ESCR0"),
69/* 18 */ P4_REGMAP(0x3bc, "RAT_ESCR0"),
70/* 19 */ P4_REGMAP(0x3be, "SSU_ESCR0"),
71/* 20 */ P4_REGMAP(0x3b8, "CRU_ESCR0"),
72/* 21 */ P4_REGMAP(0x3cc, "CRU_ESCR2"),
73/* 22 */ P4_REGMAP(0x3e0, "CRU_ESCR4"),
74/* 23 */ P4_REGMAP(0x360, "BPU_CCCR0"),
75/* 24 */ P4_REGMAP(0x361, "BPU_CCCR1"),
76/* 25 */ P4_REGMAP(0x364, "MS_CCCR0"),
77/* 26 */ P4_REGMAP(0x365, "MS_CCCR1"),
78/* 27 */ P4_REGMAP(0x368, "FLAME_CCCR0"),
79/* 28 */ P4_REGMAP(0x369, "FLAME_CCCR1"),
80/* 29 */ P4_REGMAP(0x36c, "IQ_CCCR0"),
81/* 30 */ P4_REGMAP(0x36d, "IQ_CCCR1"),
82/* 31 */ P4_REGMAP(0x370, "IQ_CCCR4"),
83/* 32 */ P4_REGMAP(0x3b3, "BPU_ESCR1"),
84/* 33 */ P4_REGMAP(0x3b5, "IS_ESCR1"),
85/* 34 */ P4_REGMAP(0x3ab, "MOB_ESCR1"),
86/* 35 */ P4_REGMAP(0x3b7, "ITLB_ESCR1"),
87/* 36 */ P4_REGMAP(0x3ad, "PMH_ESCR1"),
88/* 37 */ P4_REGMAP(0x3c9, "IX_ESCR1"),
89/* 38 */ P4_REGMAP(0x3a3, "FSB_ESCR1"),
90/* 39 */ P4_REGMAP(0x3a1, "BSU_ESCR1"),
91/* 40 */ P4_REGMAP(0x3c1, "MS_ESCR1"),
92/* 41 */ P4_REGMAP(0x3c5, "TC_ESCR1"),
93/* 42 */ P4_REGMAP(0x3c3, "TBPU_ESCR1"),
94/* 43 */ P4_REGMAP(0x3a7, "FLAME_ESCR1"),
95/* 44 */ P4_REGMAP(0x3a5, "FIRM_ESCR1"),
96/* 45 */ P4_REGMAP(0x3af, "SAAT_ESCR1"),
97/* 46 */ P4_REGMAP(0x3b1, "U2L_ESCR1"),
98/* 47 */ P4_REGMAP(0x3a9, "DAC_ESCR1"),
99/* 48 */ P4_REGMAP(0x3bb, "IQ_ESCR1"),
100/* 49 */ P4_REGMAP(0x3cb, "ALF_ESCR1"),
101/* 50 */ P4_REGMAP(0x3bd, "RAT_ESCR1"),
102/* 51 */ P4_REGMAP(0x3b9, "CRU_ESCR1"),
103/* 52 */ P4_REGMAP(0x3cd, "CRU_ESCR3"),
104/* 53 */ P4_REGMAP(0x3e1, "CRU_ESCR5"),
105/* 54 */ P4_REGMAP(0x362, "BPU_CCCR2"),
106/* 55 */ P4_REGMAP(0x363, "BPU_CCCR3"),
107/* 56 */ P4_REGMAP(0x366, "MS_CCCR2"),
108/* 57 */ P4_REGMAP(0x367, "MS_CCCR3"),
109/* 58 */ P4_REGMAP(0x36a, "FLAME_CCCR2"),
110/* 59 */ P4_REGMAP(0x36b, "FLAME_CCCR3"),
111/* 60 */ P4_REGMAP(0x36e, "IQ_CCCR2"),
112/* 61 */ P4_REGMAP(0x36f, "IQ_CCCR3"),
113/* 62 */ P4_REGMAP(0x371, "IQ_CCCR5"),
114/* 63 */ P4_REGMAP(0x3f2, "PEBS_MATRIX_VERT"),
115/* 64 */ P4_REGMAP(0x3f1, "PEBS_ENABLE"),
116};
117
118#define PMC_PEBS_MATRIX_VERT 63
119#define PMC_PEBS_ENABLE 64
120
122/* 0 */ P4_REGMAP(0x300, "BPU_CTR0"),
123/* 1 */ P4_REGMAP(0x301, "BPU_CTR1"),
124/* 2 */ P4_REGMAP(0x304, "MS_CTR0"),
125/* 3 */ P4_REGMAP(0x305, "MS_CTR1"),
126/* 4 */ P4_REGMAP(0x308, "FLAME_CTR0"),
127/* 5 */ P4_REGMAP(0x309, "FLAME_CTR1"),
128/* 6 */ P4_REGMAP(0x30c, "IQ_CTR0"),
129/* 7 */ P4_REGMAP(0x30d, "IQ_CTR1"),
130/* 8 */ P4_REGMAP(0x310, "IQ_CTR4"),
131/* 9 */ P4_REGMAP(0x302, "BPU_CTR2"),
132/* 10 */ P4_REGMAP(0x303, "BPU_CTR3"),
133/* 11 */ P4_REGMAP(0x306, "MS_CTR2"),
134/* 12 */ P4_REGMAP(0x307, "MS_CTR3"),
135/* 13 */ P4_REGMAP(0x30a, "FLAME_CTR2"),
136/* 14 */ P4_REGMAP(0x30b, "FLAME_CTR3"),
137/* 15 */ P4_REGMAP(0x30d, "IQ_CTR2"),
138/* 16 */ P4_REGMAP(0x30f, "IQ_CTR3"),
139/* 17 */ P4_REGMAP(0x311, "IQ_CTR5"),
140};
141
142/* This array provides values for the PEBS_ENABLE and PEBS_MATRIX_VERT
143 registers to support a series of metric for replay_event.
144 The first two entries are dummies; the remaining 9 correspond to
145 virtual bit masks in the replay_event definition and map onto Intel
146 documentation.
147*/
148
149#define P4_REPLAY_REAL_MASK 0x00000003
150#define P4_REPLAY_VIRT_MASK 0x00000FFC
151
153/* 0 */ {.enb = 0, /* dummy */
154 .mat_vert = 0,
155 },
156/* 1 */ {.enb = 0, /* dummy */
157 .mat_vert = 0,
158 },
159/* 2 */ {.enb = 0x01000001, /* 1stL_cache_load_miss_retired */
160 .mat_vert = 0x00000001,
161 },
162/* 3 */ {.enb = 0x01000002, /* 2ndL_cache_load_miss_retired */
163 .mat_vert = 0x00000001,
164 },
165/* 4 */ {.enb = 0x01000004, /* DTLB_load_miss_retired */
166 .mat_vert = 0x00000001,
167 },
168/* 5 */ {.enb = 0x01000004, /* DTLB_store_miss_retired */
169 .mat_vert = 0x00000002,
170 },
171/* 6 */ {.enb = 0x01000004, /* DTLB_all_miss_retired */
172 .mat_vert = 0x00000003,
173 },
174/* 7 */ {.enb = 0x01018001, /* Tagged_mispred_branch */
175 .mat_vert = 0x00000010,
176 },
177/* 8 */ {.enb = 0x01000200, /* MOB_load_replay_retired */
178 .mat_vert = 0x00000001,
179 },
180/* 9 */ {.enb = 0x01000400, /* split_load_retired */
181 .mat_vert = 0x00000001,
182 },
183/* 10 */ {.enb = 0x01000400, /* split_store_retired */
184 .mat_vert = 0x00000002,
185 },
186};
187
188static int p4_model;
189
196static int pentium4_get_event_code(unsigned int event,
197 unsigned int pmd,
198 int *code)
199{
200 int i, j, escr, cccr;
201 int rc = PFMLIB_ERR_INVAL;
202
203 if (pmd >= PENTIUM4_NUM_PMDS && pmd != PFMLIB_CNT_FIRST) {
204 goto out;
205 }
206
207 /* Check that the specified event is allowed for the specified PMD.
208 * Each event has a specific set of ESCRs it can use, which implies
209 * a specific set of CCCRs (and thus PMDs). A specified PMD of -1
210 * means assume any allowable PMD.
211 */
212 if (pmd == PFMLIB_CNT_FIRST) {
213 *code = pentium4_events[event].event_select;
215 goto out;
216 }
217
218 for (i = 0; i < MAX_ESCRS_PER_EVENT; i++) {
219 escr = pentium4_events[event].allowed_escrs[i];
220 if (escr < 0) {
221 continue;
222 }
223
224 for (j = 0; j < MAX_CCCRS_PER_ESCR; j++) {
225 cccr = pentium4_escrs[escr].allowed_cccrs[j];
226 if (cccr < 0) {
227 continue;
228 }
229
230 if (pmd == pentium4_cccrs[cccr].pmd) {
231 *code = pentium4_events[event].event_select;
233 goto out;
234 }
235 }
236 }
237
238out:
239 return rc;
240}
241
247static char *pentium4_get_event_name(unsigned int event)
248{
249 return pentium4_events[event].name;
250}
251
257static char *pentium4_get_event_mask_name(unsigned int event, unsigned int mask)
258{
259 if (mask >= EVENT_MASK_BITS || pentium4_events[event].event_masks[mask].name == NULL)
260 return NULL;
261
262 return pentium4_events[event].event_masks[mask].name;
263}
264
271static void pentium4_get_event_counters(unsigned int event,
272 pfmlib_regmask_t *counters)
273{
274 int i, j, escr, cccr;
275
276 memset(counters, 0, sizeof(*counters));
277
278 for (i = 0; i < MAX_ESCRS_PER_EVENT; i++) {
279 escr = pentium4_events[event].allowed_escrs[i];
280 if (escr < 0) {
281 continue;
282 }
283
284 for (j = 0; j < MAX_CCCRS_PER_ESCR; j++) {
285 cccr = pentium4_escrs[escr].allowed_cccrs[j];
286 if (cccr < 0) {
287 continue;
288 }
289 pfm_regmask_set(counters, pentium4_cccrs[cccr].pmd);
290 }
291 }
292}
293
301static unsigned int pentium4_get_num_event_masks(unsigned int event)
302{
303 unsigned int i = 0;
304
305 while (pentium4_events[event].event_masks[i].name) {
306 i++;
307 }
308 return i;
309}
310
318 void *model_input,
319 pfmlib_output_param_t *output,
320 void *model_output)
321{
322 unsigned int assigned_pmcs[PENTIUM4_NUM_PMCS] = {0};
323 unsigned int event, event_mask, mask;
324 unsigned int bit, tag_value, tag_enable;
325 unsigned int plm;
326 unsigned int i, j, k, m, n;
327 int escr, escr_pmc;
328 int cccr, cccr_pmc, cccr_pmd;
329 int assigned;
330 pentium4_escr_value_t escr_value;
331 pentium4_cccr_value_t cccr_value;
332
333 if (input->pfp_event_count > PENTIUM4_NUM_PMDS) {
334 /* Can't specify more events than we have counters. */
335 return PFMLIB_ERR_TOOMANY;
336 }
337
338 if (input->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
339 /* Can't specify privilege levels 1 or 2. */
340 return PFMLIB_ERR_INVAL;
341 }
342
343 /* Examine each event specified in input->pfp_events. i counts
344 * through the input->pfp_events array, and j counts through the
345 * PMCs in output->pfp_pmcs as they are set up.
346 */
347 for (i = 0, j = 0; i < input->pfp_event_count; i++) {
348
349 if (input->pfp_events[i].plm & (PFM_PLM1|PFM_PLM2)) {
350 /* Can't specify privilege levels 1 or 2. */
351 return PFMLIB_ERR_INVAL;
352 }
353
354 /*
355 * INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott)
356 */
357 if (input->pfp_events[i].event == PME_INSTR_COMPLETED &&
358 p4_model != 3 && p4_model != 4 && p4_model != 6)
360
361 event = input->pfp_events[i].event;
362 assigned = 0;
363
364 /* Use the event-specific privilege mask if set.
365 * Otherwise use the default privilege mask.
366 */
367 plm = input->pfp_events[i].plm ?
368 input->pfp_events[i].plm : input->pfp_dfl_plm;
369
370 /* Examine each ESCR that this event could be assigned to. */
371 for (k = 0; k < MAX_ESCRS_PER_EVENT && !assigned; k++) {
372 escr = pentium4_events[event].allowed_escrs[k];
373 if (escr < 0)
374 continue;
375
376 /* Make sure this ESCR isn't already assigned
377 * and isn't on the "unavailable" list.
378 */
379 escr_pmc = pentium4_escrs[escr].pmc;
380 if (assigned_pmcs[escr_pmc] ||
381 pfm_regmask_isset(&input->pfp_unavail_pmcs, escr_pmc)) {
382 continue;
383 }
384
385 /* Examine each CCCR that can be used with this ESCR. */
386 for (m = 0; m < MAX_CCCRS_PER_ESCR && !assigned; m++) {
387 cccr = pentium4_escrs[escr].allowed_cccrs[m];
388 if (cccr < 0) {
389 continue;
390 }
391
392 /* Make sure this CCCR isn't already assigned
393 * and isn't on the "unavailable" list.
394 */
395 cccr_pmc = pentium4_cccrs[cccr].pmc;
396 cccr_pmd = pentium4_cccrs[cccr].pmd;
397 if (assigned_pmcs[cccr_pmc] ||
398 pfm_regmask_isset(&input->pfp_unavail_pmcs, cccr_pmc)) {
399 continue;
400 }
401
402 /* Found an available ESCR/CCCR pair. */
403 assigned = 1;
404 assigned_pmcs[escr_pmc] = 1;
405 assigned_pmcs[cccr_pmc] = 1;
406
407 /* Calculate the event-mask value. Invalid masks
408 * specified by the caller are ignored.
409 */
410 event_mask = 0;
411 tag_value = 0;
412 tag_enable = 0;
413 for (n = 0; n < input->pfp_events[i].num_masks; n++) {
414 mask = input->pfp_events[i].unit_masks[n];
415 bit = pentium4_events[event].event_masks[mask].bit;
416 if (bit < EVENT_MASK_BITS &&
417 pentium4_events[event].event_masks[mask].name) {
418 event_mask |= (1 << bit);
419 }
420 if (bit >= EVENT_MASK_BITS &&
421 pentium4_events[event].event_masks[mask].name) {
422 tag_value |= (1 << (bit - EVENT_MASK_BITS));
423 tag_enable = 1;
424 }
425 }
426
427 /* Set up the ESCR and CCCR register values. */
428 escr_value.val = 0;
429
430 escr_value.bits.t1_usr = 0; /* controlled by kernel */
431 escr_value.bits.t1_os = 0; /* controlled by kernel */
432 escr_value.bits.t0_usr = (plm & PFM_PLM3) ? 1 : 0;
433 escr_value.bits.t0_os = (plm & PFM_PLM0) ? 1 : 0;
434 escr_value.bits.tag_enable = tag_enable;
435 escr_value.bits.tag_value = tag_value;
436 escr_value.bits.event_mask = event_mask;
437 escr_value.bits.event_select = pentium4_events[event].event_select;
438 escr_value.bits.reserved = 0;
439
440 cccr_value.val = 0;
441
442 cccr_value.bits.reserved1 = 0;
443 cccr_value.bits.enable = 1;
444 cccr_value.bits.escr_select = pentium4_events[event].escr_select;
445 cccr_value.bits.active_thread = 3; /* FIXME: This is set to count when either logical
446 * CPU is active. Need a way to distinguish
447 * between logical CPUs when HT is enabled. */
448 cccr_value.bits.compare = 0; /* FIXME: What do we do with "threshold" settings? */
449 cccr_value.bits.complement = 0; /* FIXME: What do we do with "threshold" settings? */
450 cccr_value.bits.threshold = 0; /* FIXME: What do we do with "threshold" settings? */
451 cccr_value.bits.force_ovf = 0; /* FIXME: Do we want to allow "forcing" overflow
452 * interrupts on all counter increments? */
453 cccr_value.bits.ovf_pmi_t0 = 1;
454 cccr_value.bits.ovf_pmi_t1 = 0; /* PMI taken care of by kernel typically */
455 cccr_value.bits.reserved2 = 0;
456 cccr_value.bits.cascade = 0; /* FIXME: How do we handle "cascading" counters? */
457 cccr_value.bits.overflow = 0;
458
459 /* Special processing for the replay event:
460 Remove virtual mask bits from actual mask;
461 scan mask bit list and OR bit values for each virtual mask
462 into the PEBS ENABLE and PEBS MATRIX VERT registers */
463 if (event == PME_REPLAY_EVENT) {
464 escr_value.bits.event_mask &= P4_REPLAY_REAL_MASK; /* remove virtual mask bits */
465 if (event_mask & P4_REPLAY_VIRT_MASK) { /* find a valid virtual mask */
466 output->pfp_pmcs[j].reg_value = 0;
467 output->pfp_pmcs[j].reg_num = PMC_PEBS_ENABLE;
469 output->pfp_pmcs[j+1].reg_value = 0;
472 for (n = 0; n < input->pfp_events[i].num_masks; n++) {
473 mask = input->pfp_events[i].unit_masks[n];
474 if (mask > 1 && mask < 11) { /* process each valid mask we find */
475 output->pfp_pmcs[j].reg_value |= p4_replay_regs[mask].enb;
476 output->pfp_pmcs[j+1].reg_value |= p4_replay_regs[mask].mat_vert;
477 }
478 }
479 j += 2;
480 output->pfp_pmc_count += 2;
481 }
482 }
483
484 /* Set up the PMCs in the
485 * output->pfp_pmcs array.
486 */
487 output->pfp_pmcs[j].reg_num = escr_pmc;
488 output->pfp_pmcs[j].reg_value = escr_value.val;
489 output->pfp_pmcs[j].reg_addr = p4_pmc_regmap[escr_pmc].addr;
490 j++;
491
492 __pfm_vbprintf("[%s(pmc%u)=0x%lx os=%u usr=%u tag=%u tagval=0x%x mask=%u sel=0x%x] %s\n",
493 p4_pmc_regmap[escr_pmc].name,
494 escr_pmc,
495 escr_value.val,
496 escr_value.bits.t0_os,
497 escr_value.bits.t0_usr,
498 escr_value.bits.tag_enable,
499 escr_value.bits.tag_value,
500 escr_value.bits.event_mask,
501 escr_value.bits.event_select,
502 pentium4_events[event].name);
503
504 output->pfp_pmcs[j].reg_num = cccr_pmc;
505 output->pfp_pmcs[j].reg_value = cccr_value.val;
506 output->pfp_pmcs[j].reg_addr = p4_pmc_regmap[cccr_pmc].addr;
507
508 output->pfp_pmds[i].reg_num = cccr_pmd;
509 output->pfp_pmds[i].reg_addr = p4_pmd_regmap[cccr_pmd].addr;
510
511 __pfm_vbprintf("[%s(pmc%u)=0x%lx ena=1 sel=0x%x cmp=%u cmpl=%u thres=%u edg=%u cas=%u] %s\n",
512 p4_pmc_regmap[cccr_pmc].name,
513 cccr_pmc,
514 cccr_value.val,
515 cccr_value.bits.escr_select,
516 cccr_value.bits.compare,
517 cccr_value.bits.complement,
518 cccr_value.bits.threshold,
519 cccr_value.bits.edge,
520 cccr_value.bits.cascade,
521 pentium4_events[event].name);
522 __pfm_vbprintf("[%s(pmd%u)]\n", p4_pmd_regmap[output->pfp_pmds[i].reg_num].name, output->pfp_pmds[i].reg_num);
523 j++;
524
525 output->pfp_pmc_count += 2;
526 }
527 }
528 if (k == MAX_ESCRS_PER_EVENT && !assigned) {
529 /* Couldn't find an available ESCR and/or CCCR. */
530 return PFMLIB_ERR_NOASSIGN;
531 }
532 }
533 output->pfp_pmd_count = input->pfp_event_count;
534
535 return PFMLIB_SUCCESS;
536}
537
544static int pentium4_pmu_detect(void)
545{
546 int ret, family;
547 char buffer[128];
548
549 ret = __pfm_getcpuinfo_attr("vendor_id", buffer, sizeof(buffer));
550 if (ret == -1)
551 return PFMLIB_ERR_NOTSUPP;
552
553 if (strcmp(buffer, "GenuineIntel"))
554 return PFMLIB_ERR_NOTSUPP;
555
556 ret = __pfm_getcpuinfo_attr("cpu family", buffer, sizeof(buffer));
557 if (ret == -1)
558 return PFMLIB_ERR_NOTSUPP;
559
560 family = atoi(buffer);
561
562 ret = __pfm_getcpuinfo_attr("model", buffer, sizeof(buffer));
563 if (ret == -1)
564 return PFMLIB_ERR_NOTSUPP;
565
566 /*
567 * we use model to detect model 2 which has one more counter IQ_ESCR1
568 */
569 p4_model = atoi(buffer);
570 if (family != 15)
571 return PFMLIB_ERR_NOTSUPP;
572 /*
573 * IQ_ESCR0, IQ_ESCR1 only for model 1 and 2
574 */
575 if (p4_model >2)
577
579}
580
590{
591 unsigned int i;
592
593 for(i = 0; i < PENTIUM4_NUM_PMCS; i++) {
594 pfm_regmask_set(impl_pmcs, i);
595 }
596 /*
597 * IQ_ESCR0, IQ_ESCR1 only available on model 1 and 2
598 */
599 if (p4_model > 2) {
600 pfm_regmask_clr(impl_pmcs, 16);
601 pfm_regmask_clr(impl_pmcs, 48);
602 }
603}
604
614{
615 unsigned int i;
616
617 for(i = 0; i < PENTIUM4_NUM_PMDS; i++) {
618 pfm_regmask_set(impl_pmds, i);
619 }
620}
621
631{
632 pentium4_get_impl_pmds(impl_counters);
633}
634
640static void pentium4_get_hw_counter_width(unsigned int *width)
641{
642 *width = PENTIUM4_COUNTER_WIDTH;
643}
644
654static int pentium4_get_event_desc(unsigned int event, char **desc)
655{
656 if (pentium4_events[event].desc) {
657 *desc = strdup(pentium4_events[event].desc);
658 } else {
659 *desc = NULL;
660 }
661
662 return PFMLIB_SUCCESS;
663}
664
670static int pentium4_get_event_mask_desc(unsigned int event,
671 unsigned int mask, char **desc)
672{
673 if (mask >= EVENT_MASK_BITS || pentium4_events[event].event_masks[mask].desc == NULL)
674 return PFMLIB_ERR_INVAL;
675
676 *desc = strdup(pentium4_events[event].event_masks[mask].desc);
677
678 return PFMLIB_SUCCESS;
679}
680
681static int pentium4_get_event_mask_code(unsigned int event,
682 unsigned int mask, unsigned int *code)
683{
684 *code = 1U << pentium4_events[event].event_masks[mask].bit;
685 return PFMLIB_SUCCESS;
686}
687
688static int
690{
692 e->num_masks = 1;
693 e->unit_masks[0] = 0;
694 return PFMLIB_SUCCESS;
695
696}
697
698static int
700{
701 /*
702 * some models do not implement INSTR_COMPLETED
703 */
704 if (p4_model != 3 && p4_model != 4 && p4_model != 6) {
706 e->num_masks = 2;
707 e->unit_masks[0] = 0;
708 e->unit_masks[1] = 1;
709 } else {
711 e->num_masks = 1;
712 e->unit_masks[0] = 0;
713 }
714 return PFMLIB_SUCCESS;
715}
716
721 .pmu_name = "Pentium4/Xeon/EM64T",
722 .pmu_type = PFMLIB_PENTIUM4_PMU,
723 .pme_count = PENTIUM4_EVENT_COUNT,
724 .pmd_count = PENTIUM4_NUM_PMDS,
725 .pmc_count = PENTIUM4_NUM_PMCS,
726 .num_cnt = PENTIUM4_NUM_PMDS,
727 .get_event_code = pentium4_get_event_code,
728 .get_event_name = pentium4_get_event_name,
729 .get_event_mask_name = pentium4_get_event_mask_name,
730 .get_event_counters = pentium4_get_event_counters,
731 .get_num_event_masks = pentium4_get_num_event_masks,
732 .dispatch_events = pentium4_dispatch_events,
733 .pmu_detect = pentium4_pmu_detect,
734 .get_impl_pmcs = pentium4_get_impl_pmcs,
735 .get_impl_pmds = pentium4_get_impl_pmds,
736 .get_impl_counters = pentium4_get_impl_counters,
737 .get_hw_counter_width = pentium4_get_hw_counter_width,
738 .get_event_desc = pentium4_get_event_desc,
739 .get_event_mask_desc = pentium4_get_event_mask_desc,
740 .get_event_mask_code = pentium4_get_event_mask_code,
741 .get_cycle_event = pentium4_get_cycle_event,
742 .get_inst_retired_event = pentium4_get_inst_retired
743};
744
int i
#define PENTIUM4_COUNTER_WIDTH
#define PME_REPLAY_EVENT
#define PENTIUM4_INST_RETIRED
#define PENTIUM4_CPU_CLK_UNHALTED
#define PENTIUM4_NUM_PMDS
#define PME_INSTR_COMPLETED
#define PENTIUM4_EVENT_COUNT
#define PENTIUM4_NUM_PMCS
pentium4_escr_reg_t pentium4_escrs[]
pentium4_cccr_reg_t pentium4_cccrs[]
pentium4_event_t pentium4_events[]
#define PFM_PLM2
Definition: pfmlib.h:52
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
#define PFM_PLM3
Definition: pfmlib.h:53
#define PFMLIB_ERR_EVTINCOMP
Definition: pfmlib.h:294
#define PFMLIB_ERR_INVAL
Definition: pfmlib.h:285
static int pfm_regmask_clr(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:332
#define PFMLIB_ERR_TOOMANY
Definition: pfmlib.h:295
#define PFM_PLM0
Definition: pfmlib.h:50
static int pfm_regmask_isset(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:313
#define PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
#define PFMLIB_PENTIUM4_PMU
Definition: pfmlib.h:230
#define PFM_PLM1
Definition: pfmlib.h:51
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
int family
Definition: pfmlib_amd64.c:85
int __pfm_getcpuinfo_attr(const char *attr, char *ret_buf, size_t maxlen)
static void pentium4_get_impl_pmcs(pfmlib_regmask_t *impl_pmcs)
static char * pentium4_get_event_name(unsigned int event)
static int pentium4_get_event_code(unsigned int event, unsigned int pmd, int *code)
static int pentium4_dispatch_events(pfmlib_input_param_t *input, void *model_input, pfmlib_output_param_t *output, void *model_output)
static void pentium4_get_impl_counters(pfmlib_regmask_t *impl_counters)
#define P4_REPLAY_REAL_MASK
static char * pentium4_get_event_mask_name(unsigned int event, unsigned int mask)
static int pentium4_pmu_detect(void)
static unsigned int pentium4_get_num_event_masks(unsigned int event)
static int pentium4_get_cycle_event(pfmlib_event_t *e)
#define P4_REGMAP(a, n)
#define PMC_PEBS_MATRIX_VERT
static p4_regmap_t p4_pmc_regmap[]
static int pentium4_get_event_desc(unsigned int event, char **desc)
static void pentium4_get_hw_counter_width(unsigned int *width)
static void pentium4_get_impl_pmds(pfmlib_regmask_t *impl_pmds)
static int pentium4_get_event_mask_code(unsigned int event, unsigned int mask, unsigned int *code)
#define PMC_PEBS_ENABLE
static void pentium4_get_event_counters(unsigned int event, pfmlib_regmask_t *counters)
static int pentium4_get_event_mask_desc(unsigned int event, unsigned int mask, char **desc)
static int p4_model
static int pentium4_get_inst_retired(pfmlib_event_t *e)
#define P4_REPLAY_VIRT_MASK
static pentium4_replay_regs_t p4_replay_regs[]
static p4_regmap_t p4_pmd_regmap[]
pfm_pmu_support_t pentium4_support
#define EVENT_MASK_BITS
#define MAX_CCCRS_PER_ESCR
#define MAX_ESCRS_PER_EVENT
void __pfm_vbprintf(const char *fmt,...)
Definition: pfmlib_priv.c:52
#define PFMLIB_CNT_FIRST
Definition: pfmlib_priv.h:62
rc
Definition: pscanf.h:23
const char * name
Definition: rocs.c:225
unsigned long addr
int allowed_cccrs[MAX_CCCRS_PER_ESCR]
int allowed_escrs[MAX_ESCRS_PER_EVENT]
pentium4_event_mask_t event_masks[EVENT_MASK_BITS]
unsigned int pmc_count
Definition: pfmlib_priv.h:37
unsigned int num_masks
Definition: pfmlib.h:90
unsigned int plm
Definition: pfmlib.h:87
unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT]
Definition: pfmlib.h:89
unsigned int event
Definition: pfmlib.h:86
unsigned int pfp_dfl_plm
Definition: pfmlib.h:110
pfmlib_regmask_t pfp_unavail_pmcs
Definition: pfmlib.h:114
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:113
unsigned int pfp_event_count
Definition: pfmlib.h:109
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS]
Definition: pfmlib.h:130
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:129
unsigned int pfp_pmc_count
Definition: pfmlib.h:127
unsigned int pfp_pmd_count
Definition: pfmlib.h:128
unsigned long long reg_value
Definition: pfmlib.h:98
unsigned int reg_num
Definition: pfmlib.h:100
unsigned long long reg_addr
Definition: pfmlib.h:99
unsigned long escr_select
unsigned long complement
unsigned long ovf_pmi_t0
unsigned long ovf_pmi_t1
unsigned long active_thread
struct pentium4_cccr_value_t::@86 bits
unsigned long tag_enable
unsigned long reserved
unsigned long event_select
struct pentium4_escr_value_t::@85 bits
unsigned long tag_value
unsigned long event_mask