PAPI 7.1.0.0
Loading...
Searching...
No Matches
pfmlib_montecito.c
Go to the documentation of this file.
1/*
2 * pfmlib_montecito.c : support for the Dual-Core Itanium2 processor
3 *
4 * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
5 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 * of the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <sys/types.h>
25#include <ctype.h>
26#include <string.h>
27#include <stdio.h>
28#include <stdlib.h>
29
30/* public headers */
32
33/* private headers */
34#include "pfmlib_priv.h" /* library private */
35#include "pfmlib_priv_ia64.h" /* architecture private */
36#include "pfmlib_montecito_priv.h" /* PMU private */
37#include "montecito_events.h" /* PMU private */
38
39#define is_ear(i) event_is_ear(montecito_pe+(i))
40#define is_ear_tlb(i) event_is_ear_tlb(montecito_pe+(i))
41#define is_ear_alat(i) event_is_ear_alat(montecito_pe+(i))
42#define is_ear_cache(i) event_is_ear_cache(montecito_pe+(i))
43#define is_iear(i) event_is_iear(montecito_pe+(i))
44#define is_dear(i) event_is_dear(montecito_pe+(i))
45#define is_etb(i) event_is_etb(montecito_pe+(i))
46#define has_opcm(i) event_opcm_ok(montecito_pe+(i))
47#define has_iarr(i) event_iarr_ok(montecito_pe+(i))
48#define has_darr(i) event_darr_ok(montecito_pe+(i))
49#define has_all(i) event_all_ok(montecito_pe+(i))
50#define has_mesi(i) event_mesi_ok(montecito_pe+(i))
51
52#define evt_use_opcm(e) ((e)->pfp_mont_opcm1.opcm_used != 0 || (e)->pfp_mont_opcm2.opcm_used !=0)
53#define evt_use_irange(e) ((e)->pfp_mont_irange.rr_used)
54#define evt_use_drange(e) ((e)->pfp_mont_drange.rr_used)
55
56#define evt_grp(e) (int)montecito_pe[e].pme_qualifiers.pme_qual.pme_group
57#define evt_set(e) (int)montecito_pe[e].pme_qualifiers.pme_qual.pme_set
58#define evt_umask(e) montecito_pe[e].pme_umask
59#define evt_type(e) (int)montecito_pe[e].pme_type
60#define evt_caf(e) (int)montecito_pe[e].pme_caf
61
62#define FINE_MODE_BOUNDARY_BITS 16
63#define FINE_MODE_MASK ~((1U<<FINE_MODE_BOUNDARY_BITS)-1)
64
65/* let's define some handy shortcuts! */
66#define pmc_plm pmc_mont_counter_reg.pmc_plm
67#define pmc_ev pmc_mont_counter_reg.pmc_ev
68#define pmc_oi pmc_mont_counter_reg.pmc_oi
69#define pmc_pm pmc_mont_counter_reg.pmc_pm
70#define pmc_es pmc_mont_counter_reg.pmc_es
71#define pmc_umask pmc_mont_counter_reg.pmc_umask
72#define pmc_thres pmc_mont_counter_reg.pmc_thres
73#define pmc_all pmc_mont_counter_reg.pmc_all
74#define pmc_ism pmc_mont_counter_reg.pmc_ism
75#define pmc_m pmc_mont_counter_reg.pmc_m
76#define pmc_e pmc_mont_counter_reg.pmc_e
77#define pmc_s pmc_mont_counter_reg.pmc_s
78#define pmc_i pmc_mont_counter_reg.pmc_i
79
80#define UNEXISTING_SET 0xff
81
82static char * pfm_mont_get_event_name(unsigned int i);
83/*
84 * Description of the PMC register mappings use by
85 * this module (as reported in pfmlib_reg_t.reg_num):
86 *
87 * 0 -> PMC0
88 * 1 -> PMC1
89 * n -> PMCn
90 *
91 * The following are in the model specific rr_br[]:
92 * IBR0 -> 0
93 * IBR1 -> 1
94 * ...
95 * IBR7 -> 7
96 * DBR0 -> 0
97 * DBR1 -> 1
98 * ...
99 * DBR7 -> 7
100 *
101 * We do not use a mapping table, instead we make up the
102 * values on the fly given the base.
103 */
104
105static int
107{
108 int tmp;
109 int ret = PFMLIB_ERR_NOTSUPP;
110
112 if (tmp == 0x20) {
113 ret = PFMLIB_SUCCESS;
114 }
115 return ret;
116}
117
118/*
119 * Check the event for incompatibilities. This is useful
120 * for L1D and L2D related events. Due to wire limitations,
121 * some caches events are separated into sets. There
122 * are 6 sets for the L1D cache group and 8 sets for L2D group.
123 * It is NOT possible to simultaneously measure events from
124 * differents sets for L1D. For instance, you cannot
125 * measure events from set0 and set1 in L1D cache group. The L2D
126 * group allows up to two different sets to be active at the same
127 * time. The first set is selected by the event in PMC4 and the second
128 * set by the event in PMC6. Once the set is selected for PMC4,
129 * the same set is locked for PMC5 and PMC8. Similarly, once the
130 * set is selected for PMC6, the same set is locked for PMC7 and
131 * PMC9.
132 *
133 * This function verifies that only one set of L1D is selected
134 * and that no more than 2 sets are selected for L2D
135 */
136static int
137check_cross_groups(pfmlib_input_param_t *inp, unsigned int *l1d_event,
138 unsigned long *l2d_set1_mask, unsigned long *l2d_set2_mask)
139{
140 int g, s, s1, s2;
141 unsigned int cnt = inp->pfp_event_count;
142 pfmlib_event_t *e = inp->pfp_events;
143 unsigned int i, j;
144 unsigned long l2d_mask1 = 0, l2d_mask2 = 0;
145 unsigned int l1d_event_idx = UNEXISTING_SET;
146
147 /*
148 * Let check the L1D constraint first
149 *
150 * There is no umask restriction for this group
151 */
152 for (i=0; i < cnt; i++) {
153 g = evt_grp(e[i].event);
154 s = evt_set(e[i].event);
155
156 if (g != PFMLIB_MONT_EVT_L1D_CACHE_GRP) continue;
157 DPRINT("i=%u g=%d s=%d\n", i, g, s);
158 l1d_event_idx = i;
159 for (j=i+1; j < cnt; j++) {
160 if (evt_grp(e[j].event) != g) continue;
161 /*
162 * if there is another event from the same group
163 * but with a different set, then we return an error
164 */
165 if (evt_set(e[j].event) != s) return PFMLIB_ERR_EVTSET;
166 }
167 }
168
169 /*
170 * Check that we have only up to two distinct
171 * sets for L2D
172 */
173 s1 = s2 = -1;
174 for (i=0; i < cnt; i++) {
175 g = evt_grp(e[i].event);
176
177 if (g != PFMLIB_MONT_EVT_L2D_CACHE_GRP) continue;
178
179 s = evt_set(e[i].event);
180
181 /*
182 * we have seen this set before, continue
183 */
184 if (s1 == s) {
185 l2d_mask1 |= 1UL << i;
186 continue;
187 }
188 if (s2 == s) {
189 l2d_mask2 |= 1UL << i;
190 continue;
191 }
192 /*
193 * record first of second set seen
194 */
195 if (s1 == -1) {
196 s1 = s;
197 l2d_mask1 |= 1UL << i;
198 } else if (s2 == -1) {
199 s2 = s;
200 l2d_mask2 |= 1UL << i;
201 } else {
202 /*
203 * found a third set, that's not possible
204 */
205 return PFMLIB_ERR_EVTSET;
206 }
207 }
208 *l1d_event = l1d_event_idx;
209 *l2d_set1_mask = l2d_mask1;
210 *l2d_set2_mask = l2d_mask2;
211
212 return PFMLIB_SUCCESS;
213}
214
215/*
216 * Certain prefetch events must be treated specially when instruction range restriction
217 * is used because they can only be constrained by IBRP1 in fine-mode. Other events
218 * will use IBRP0 if tagged as a demand fetch OR IBPR1 if tagged as a prefetch match.
219 *
220 * Events which can be qualified by the two pairs depending on their tag:
221 * - ISB_BUNPAIRS_IN
222 * - L1I_FETCH_RAB_HIT
223 * - L1I_FETCH_ISB_HIT
224 * - L1I_FILLS
225 *
226 * This function returns the number of qualifying prefetch events found
227 */
228static int prefetch_events[]={
232};
233#define NPREFETCH_EVENTS sizeof(prefetch_events)/sizeof(int)
234
236{
241};
242#define NPREFETCH_DUAL_EVENTS sizeof(prefetch_dual_events)/sizeof(int)
243
244/*
245 * prefetch events must use IBRP1, unless they are dual and the user specified
246 * PFMLIB_MONT_IRR_DEMAND_FETCH in rr_flags
247 */
248static int
249check_prefetch_events(pfmlib_input_param_t *inp, pfmlib_mont_input_rr_t *irr, unsigned int *count, int *base_idx, int *dup)
250{
251 int code;
252 int prefetch_codes[NPREFETCH_EVENTS];
253 int prefetch_dual_codes[NPREFETCH_DUAL_EVENTS];
254 unsigned int i, j;
255 int c, flags;
256 int found = 0, found_ibrp0 = 0, found_ibrp1 = 0;
257
259
260 for(i=0; i < NPREFETCH_EVENTS; i++) {
262 prefetch_codes[i] = code;
263 }
264
265 for(i=0; i < NPREFETCH_DUAL_EVENTS; i++) {
267 prefetch_dual_codes[i] = code;
268 }
269
270 for(i=0; i < inp->pfp_event_count; i++) {
272
273 for(j=0; j < NPREFETCH_EVENTS; j++) {
274 if (c == prefetch_codes[j]) {
275 found++;
276 found_ibrp1++;
277 }
278 }
279 /*
280 * for the dual events, users must specify one or both of the
281 * PFMLIB_MONT_IRR_DEMAND_FETCH or PFMLIB_MONT_IRR_PREFETCH_MATCH
282 */
283 for(j=0; j < NPREFETCH_DUAL_EVENTS; j++) {
284 if (c == prefetch_dual_codes[j]) {
285 found++;
286 if (flags == 0)
287 return PFMLIB_ERR_IRRFLAGS;
289 found_ibrp0++;
291 found_ibrp1++;
292 }
293 }
294 }
295 *count = found;
296 *dup = 0;
297
298 /*
299 * if both found_ibrp0 and found_ibrp1 > 0, then we need to duplicate
300 * the range in ibrp0 to ibrp1.
301 */
302 if (found) {
303 *base_idx = found_ibrp0 ? 0 : 2;
304 if (found_ibrp1 && found_ibrp0)
305 *dup = 1;
306 }
307 return 0;
308}
309
310/*
311 * look for CPU_OP_CYCLES_QUAL
312 * Return:
313 * 1 if found
314 * 0 otherwise
315 */
316static int
318{
319 unsigned int i;
320 int code, c;
321
323
324 for(i=0; i < inp->pfp_event_count; i++) {
326 if (c == code)
327 return 1;
328 }
329 return 0;
330}
331
332/*
333 * IA64_INST_RETIRED (and subevents) is the only event which can be measured on all
334 * 4 IBR when non-fine mode is not possible.
335 *
336 * This function returns:
337 * - the number of events match the IA64_INST_RETIRED code
338 * - in retired_mask to bottom 4 bits indicates which of the 4 INST_RETIRED event
339 * is present
340 */
341static unsigned int
342check_inst_retired_events(pfmlib_input_param_t *inp, unsigned long *retired_mask)
343{
344 int code;
345 int c;
346 unsigned int i, count, found = 0;
347 unsigned long umask, mask;
348
350
351 count = inp->pfp_event_count;
352 mask = 0;
353 for(i=0; i < count; i++) {
355 if (c == code) {
357 switch(umask) {
358 case 0: mask |= 1;
359 break;
360 case 1: mask |= 2;
361 break;
362 case 2: mask |= 4;
363 break;
364 case 3: mask |= 8;
365 break;
366 }
367 found++;
368 }
369 }
370 if (retired_mask) *retired_mask = mask;
371 return found;
372}
373
374static int
376{
378 int i;
379
380 for(i=0; i < n; i++) {
381 if ((lim[i].rr_start & FINE_MODE_MASK) != (lim[i].rr_end & FINE_MODE_MASK))
382 return 0;
383 }
384 return 1;
385}
386
387/*
388 * mode = 0 -> check code (enforce bundle alignment)
389 * mode = 1 -> check data
390 */
391static int
392check_intervals(pfmlib_mont_input_rr_t *irr, int mode, unsigned int *n_intervals)
393{
394 unsigned int i;
396
397 for(i=0; i < 4; i++) {
398 /* end marker */
399 if (lim[i].rr_start == 0 && lim[i].rr_end == 0) break;
400
401 /* invalid entry */
402 if (lim[i].rr_start >= lim[i].rr_end) return PFMLIB_ERR_IRRINVAL;
403
404 if (mode == 0 && (lim[i].rr_start & 0xf || lim[i].rr_end & 0xf))
405 return PFMLIB_ERR_IRRALIGN;
406 }
407 *n_intervals = i;
408 return PFMLIB_SUCCESS;
409}
410
411/*
412 * It is not possible to measure more than one of the
413 * L2D_OZQ_CANCELS0, L2D_OZQ_CANCELS1 at the same time.
414 */
415
416static int cancel_events[]=
417{
420};
421#define NCANCEL_EVENTS sizeof(cancel_events)/sizeof(int)
422
423static int
425{
426 unsigned int i, j, count;
427 int code;
428 int cancel_codes[NCANCEL_EVENTS];
429 int idx = -1;
430
431 for(i=0; i < NCANCEL_EVENTS; i++) {
433 cancel_codes[i] = code;
434 }
435 count = inp->pfp_event_count;
436 for(i=0; i < count; i++) {
437 for (j=0; j < NCANCEL_EVENTS; j++) {
438 pfm_get_event_code(inp->pfp_events[i].event, &code);
439 if (code == cancel_codes[j]) {
440 if (idx != -1) {
441 return PFMLIB_ERR_INVAL;
442 }
443 idx = inp->pfp_events[i].event;
444 }
445 }
446 }
447 return PFMLIB_SUCCESS;
448}
449
450/*
451 * Automatically dispatch events to corresponding counters following constraints.
452 */
453static unsigned int l2d_set1_cnts[]={ 4, 5, 8 };
454static unsigned int l2d_set2_cnts[]={ 6, 7, 9 };
455
456static int
458{
459 pfmlib_mont_input_param_t *param = mod_in;
462 pfmlib_reg_t *pc, *pd;
463 pfmlib_regmask_t avail_cntrs, impl_cntrs;
464 unsigned int i,j, k, max_cnt;
465 unsigned int assign[PMU_MONT_NUM_COUNTERS];
466 unsigned int m, cnt;
467 unsigned int l1d_set;
468 unsigned long l2d_set1_mask, l2d_set2_mask, evt_mask, mesi;
469 unsigned long not_assigned_events, cnt_mask;
470 int l2d_set1_p, l2d_set2_p;
471 int ret;
472
473 e = inp->pfp_events;
474 pc = outp->pfp_pmcs;
475 pd = outp->pfp_pmds;
476 cnt = inp->pfp_event_count;
477
478 if (PFMLIB_DEBUG())
479 for (m=0; m < cnt; m++) {
480 DPRINT("ev[%d]=%s counters=0x%lx\n", m, montecito_pe[e[m].event].pme_name,
481 montecito_pe[e[m].event].pme_counters);
482 }
483
485
486 l1d_set = UNEXISTING_SET;
487 ret = check_cross_groups(inp, &l1d_set, &l2d_set1_mask, &l2d_set2_mask);
488 if (ret != PFMLIB_SUCCESS) return ret;
489
490 ret = check_cancel_events(inp);
491 if (ret != PFMLIB_SUCCESS) return ret;
492
493 /*
494 * at this point, we know that:
495 * - we have at most 1 L1D set
496 * - we have at most 2 L2D sets
497 * - cancel events are compatible
498 */
499
500 DPRINT("l1d_set=%u l2d_set1_mask=0x%lx l2d_set2_mask=0x%lx\n", l1d_set, l2d_set1_mask, l2d_set2_mask);
501
502 /*
503 * first, place L1D cache event in PMC5
504 *
505 * this is the strongest constraint
506 */
507 pfm_get_impl_counters(&impl_cntrs);
508 pfm_regmask_andnot(&avail_cntrs, &impl_cntrs, &inp->pfp_unavail_pmcs);
509 not_assigned_events = 0;
510
511 DPRINT("avail_cntrs=0x%lx\n", avail_cntrs.bits[0]);
512
513 /*
514 * we do not check ALL_THRD here because at least
515 * one event has to be in PMC5 for this group
516 */
517 if (l1d_set != UNEXISTING_SET) {
518
519 if (!pfm_regmask_isset(&avail_cntrs, 5))
520 return PFMLIB_ERR_NOASSIGN;
521
522 assign[l1d_set] = 5;
523
524 pfm_regmask_clr(&avail_cntrs, 5);
525 }
526
527 l2d_set1_p = l2d_set2_p = 0;
528
529 /*
530 * assign L2D set1 and set2 counters
531 */
532 for (i=0; i < cnt ; i++) {
533 evt_mask = 1UL << i;
534 /*
535 * place l2d set1 events. First 3 go to designated
536 * counters, the rest is placed elsewhere in the final
537 * pass
538 */
539 if (l2d_set1_p < 3 && (l2d_set1_mask & evt_mask)) {
540 assign[i] = l2d_set1_cnts[l2d_set1_p];
541
542 if (!pfm_regmask_isset(&avail_cntrs, assign[i]))
543 return PFMLIB_ERR_NOASSIGN;
544
545 pfm_regmask_clr(&avail_cntrs, assign[i]);
546 l2d_set1_p++;
547 continue;
548 }
549 /*
550 * same as above but for l2d set2
551 */
552 if (l2d_set2_p < 3 && (l2d_set2_mask & evt_mask)) {
553 assign[i] = l2d_set2_cnts[l2d_set2_p];
554
555 if (!pfm_regmask_isset(&avail_cntrs, assign[i]))
556 return PFMLIB_ERR_NOASSIGN;
557
558 pfm_regmask_clr(&avail_cntrs, assign[i]);
559 l2d_set2_p++;
560 continue;
561 }
562 /*
563 * if not l2d nor l1d, then defer placement until final pass
564 */
565 if (i != l1d_set)
566 not_assigned_events |= evt_mask;
567
568 DPRINT("phase 1: i=%u avail_cntrs=0x%lx l2d_set1_p=%d l2d_set2_p=%d not_assigned=0x%lx\n",
569 i,
570 avail_cntrs.bits[0],
571 l2d_set1_p,
572 l2d_set2_p,
573 not_assigned_events);
574 }
575 /*
576 * assign BUS_* ER_* events (work only in PMC4-PMC9)
577 */
578 evt_mask = not_assigned_events;
579 for (i=0; evt_mask ; i++, evt_mask >>=1) {
580
581 if ((evt_mask & 0x1) == 0)
582 continue;
583
584 cnt_mask = montecito_pe[e[i].event].pme_counters;
585 /*
586 * only interested in events with restricted set of counters
587 */
588 if (cnt_mask == 0xfff0)
589 continue;
590
591 for(j=0; cnt_mask; j++, cnt_mask >>=1) {
592 if ((cnt_mask & 0x1) == 0)
593 continue;
594
595 DPRINT("phase 2: i=%d j=%d cnt_mask=0x%lx avail_cntrs=0x%lx not_assigned_evnts=0x%lx\n",
596 i, j, cnt_mask, avail_cntrs.bits[0], not_assigned_events);
597
598 if (!pfm_regmask_isset(&avail_cntrs, j))
599 continue;
600
601 assign[i] = j;
602 not_assigned_events &= ~(1UL << i);
603 pfm_regmask_clr(&avail_cntrs, j);
604 break;
605 }
606 if (cnt_mask == 0)
607 return PFMLIB_ERR_NOASSIGN;
608 }
609 /*
610 * assign the rest of the events (no constraints)
611 */
612 evt_mask = not_assigned_events;
614 for (i=0, j=0; evt_mask ; i++, evt_mask >>=1) {
615
616 DPRINT("phase 3a: i=%d j=%d evt_mask=0x%lx avail_cntrs=0x%lx not_assigned_evnts=0x%lx\n",
617 i, j, evt_mask, avail_cntrs.bits[0], not_assigned_events);
618 if ((evt_mask & 0x1) == 0)
619 continue;
620
621 while(j < max_cnt && !pfm_regmask_isset(&avail_cntrs, j)) {
622 DPRINT("phase 3: i=%d j=%d evt_mask=0x%lx avail_cntrs=0x%lx not_assigned_evnts=0x%lx\n",
623 i, j, evt_mask, avail_cntrs.bits[0], not_assigned_events);
624 j++;
625 }
626
627 if (j == max_cnt)
628 return PFMLIB_ERR_NOASSIGN;
629
630 assign[i] = j;
631 j++;
632 }
633
634 for (j=0; j < cnt ; j++ ) {
635 mesi = 0;
636
637 /*
638 * XXX: we do not support .all placement just yet
639 */
640 if (param && param->pfp_mont_counters[j].flags & PFMLIB_MONT_FL_EVT_ALL_THRD) {
641 DPRINT(".all mode is not yet supported by libpfm\n");
642 return PFMLIB_ERR_NOTSUPP;
643 }
644
645 if (has_mesi(e[j].event)) {
646 for(k=0;k< e[j].num_masks; k++) {
647 mesi |= 1UL << e[j].unit_masks[k];
648 }
649 /* by default we capture everything */
650 if (mesi == 0)
651 mesi = 0xf;
652 }
653 reg.pmc_val = 0; /* clear all, bits 26-27 must be zero for proper operations */
654 /* if plm is 0, then assume not specified per-event and use default */
655 reg.pmc_plm = inp->pfp_events[j].plm ? inp->pfp_events[j].plm : inp->pfp_dfl_plm;
656 reg.pmc_oi = 0; /* let the user/OS deal with this field */
657 reg.pmc_pm = inp->pfp_flags & PFMLIB_PFP_SYSTEMWIDE ? 1 : 0;
658 reg.pmc_thres = param ? param->pfp_mont_counters[j].thres: 0;
659 reg.pmc_ism = 0x2; /* force IA-64 mode */
660 reg.pmc_umask = is_ear(e[j].event) ? 0x0 : montecito_pe[e[j].event].pme_umask;
661 reg.pmc_es = montecito_pe[e[j].event].pme_code;
662 reg.pmc_all = 0; /* XXX force self for now */
663 reg.pmc_m = (mesi>>3) & 0x1;
664 reg.pmc_e = (mesi>>2) & 0x1;
665 reg.pmc_s = (mesi>>1) & 0x1;
666 reg.pmc_i = mesi & 0x1;
667 /*
668 * Note that we don't force PMC4.pmc_ena = 1 because the kernel takes care of this for us.
669 * This way we don't have to program something in PMC4 even when we don't use it
670 */
671 pc[j].reg_num = assign[j];
672 pc[j].reg_value = reg.pmc_val;
673 pc[j].reg_addr = pc[j].reg_alt_addr = assign[j];
674
675 pd[j].reg_num = assign[j];
676 pd[j].reg_addr = pd[j].reg_alt_addr = assign[j];
677
678 __pfm_vbprintf("[PMC%u(pmc%u)=0x%06lx m=%d e=%d s=%d i=%d thres=%d all=%d es=0x%02x plm=%d umask=0x%x pm=%d ism=0x%x oi=%d] %s\n",
679 assign[j],
680 assign[j],
681 reg.pmc_val,
682 reg.pmc_m,
683 reg.pmc_e,
684 reg.pmc_s,
685 reg.pmc_i,
686 reg.pmc_thres,
687 reg.pmc_all,
688 reg.pmc_es,reg.pmc_plm,
689 reg.pmc_umask, reg.pmc_pm,
690 reg.pmc_ism,
691 reg.pmc_oi,
693 __pfm_vbprintf("[PMD%u(pmd%u)]\n", pd[j].reg_num, pd[j].reg_num);
694 }
695 /* number of PMC registers programmed */
696 outp->pfp_pmc_count = cnt;
697 outp->pfp_pmd_count = cnt;
698
699 return PFMLIB_SUCCESS;
700}
701
702static int
704{
706 pfmlib_mont_input_param_t *param = mod_in;
707 pfmlib_reg_t *pc, *pd;
708 pfmlib_mont_input_param_t fake_param;
709 unsigned int pos1, pos2;
710 unsigned int i, count;
711
712 pc = outp->pfp_pmcs;
713 pd = outp->pfp_pmds;
714 pos1 = outp->pfp_pmc_count;
715 pos2 = outp->pfp_pmd_count;
716 count = inp->pfp_event_count;
717
718 for (i=0; i < count; i++) {
719 if (is_iear(inp->pfp_events[i].event)) break;
720 }
721
722 if (param == NULL || param->pfp_mont_iear.ear_used == 0) {
723
724 /*
725 * case 3: no I-EAR event, no (or nothing) in param->pfp_mont_iear.ear_used
726 */
727 if (i == count) return PFMLIB_SUCCESS;
728
729 memset(&fake_param, 0, sizeof(fake_param));
730 param = &fake_param;
731
732 /*
733 * case 1: extract all information for event (name)
734 */
736
738
739 DPRINT("I-EAR event with no info\n");
740 }
741
742 /*
743 * case 2: ear_used=1, event is defined, we use the param info as it is more precise
744 * case 4: ear_used=1, no event (free running I-EAR), use param info
745 */
746 reg.pmc_val = 0;
747
749 /* if plm is 0, then assume not specified per-event and use default */
752 reg.pmc37_mont_tlb_reg.iear_ct = 0x0;
755 /* if plm is 0, then assume not specified per-event and use default */
760 } else {
761 DPRINT("ALAT mode not supported in I-EAR mode\n");
762 return PFMLIB_ERR_INVAL;
763 }
764 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 37))
765 return PFMLIB_ERR_NOASSIGN;
766
767 pc[pos1].reg_num = 37; /* PMC37 is I-EAR config register */
768 pc[pos1].reg_value = reg.pmc_val;
769 pc[pos1].reg_addr = pc[pos1].reg_alt_addr = 37;
770 pos1++;
771
772 pd[pos2].reg_num = 34;
773 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 34;
774 pos2++;
775 pd[pos2].reg_num = 35;
776 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 35;
777 pos2++;
778
780 __pfm_vbprintf("[PMC37(pmc37)=0x%lx ctb=tlb plm=%d pm=%d umask=0x%x]\n",
781 reg.pmc_val,
785 } else {
786 __pfm_vbprintf("[PMC37(pmc37)=0x%lx ctb=cache plm=%d pm=%d umask=0x%x]\n",
787 reg.pmc_val,
791 }
792 __pfm_vbprintf("[PMD34(pmd34)]\n[PMD35(pmd35)\n");
793
794 /* update final number of entries used */
795 outp->pfp_pmc_count = pos1;
796 outp->pfp_pmd_count = pos2;
797
798 return PFMLIB_SUCCESS;
799}
800
801static int
803{
805 pfmlib_mont_input_param_t *param = mod_in;
806 pfmlib_reg_t *pc, *pd;
807 pfmlib_mont_input_param_t fake_param;
808 unsigned int pos1, pos2;
809 unsigned int i, count;
810
811 pc = outp->pfp_pmcs;
812 pd = outp->pfp_pmds;
813 pos1 = outp->pfp_pmc_count;
814 pos2 = outp->pfp_pmd_count;
815
816 count = inp->pfp_event_count;
817 for (i=0; i < count; i++) {
818 if (is_dear(inp->pfp_events[i].event)) break;
819 }
820
821 if (param == NULL || param->pfp_mont_dear.ear_used == 0) {
822
823 /*
824 * case 3: no D-EAR event, no (or nothing) in param->pfp_mont_dear.ear_used
825 */
826 if (i == count) return PFMLIB_SUCCESS;
827
828 memset(&fake_param, 0, sizeof(fake_param));
829 param = &fake_param;
830
831 /*
832 * case 1: extract all information for event (name)
833 */
835
837
838 DPRINT("D-EAR event with no info\n");
839 }
840
841 /* sanity check on the mode */
845 return PFMLIB_ERR_INVAL;
846
847 /*
848 * case 2: ear_used=1, event is defined, we use the param info as it is more precise
849 * case 4: ear_used=1, no event (free running D-EAR), use param info
850 */
851 reg.pmc_val = 0;
852
853 /* if plm is 0, then assume not specified per-event and use default */
858 reg.pmc40_mont_reg.dear_ism = 0x2; /* force IA-64 mode */
859
860 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 40))
861 return PFMLIB_ERR_NOASSIGN;
862
863 pc[pos1].reg_num = 40; /* PMC11 is D-EAR config register */
864 pc[pos1].reg_value = reg.pmc_val;
865 pc[pos1].reg_addr = pc[pos1].reg_alt_addr = 40;
866 pos1++;
867
868 pd[pos2].reg_num = 32;
869 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 32;
870 pos2++;
871 pd[pos2].reg_num = 33;
872 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 33;
873 pos2++;
874 pd[pos2].reg_num = 36;
875 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 36;
876 pos2++;
877
878 __pfm_vbprintf("[PMC40(pmc40)=0x%lx mode=%s plm=%d pm=%d ism=0x%x umask=0x%x]\n",
879 reg.pmc_val,
880 reg.pmc40_mont_reg.dear_mode == 0 ? "L1D" :
881 (reg.pmc40_mont_reg.dear_mode == 1 ? "L1DTLB" : "ALAT"),
886 __pfm_vbprintf("[PMD32(pmd32)]\n[PMD33(pmd33)\nPMD36(pmd36)\n");
887
888 /* update final number of entries used */
889 outp->pfp_pmc_count = pos1;
890 outp->pfp_pmd_count = pos2;
891
892 return PFMLIB_SUCCESS;
893}
894
895static int
897{
898 pfmlib_mont_input_param_t *param = mod_in;
899 pfmlib_reg_t *pc = outp->pfp_pmcs;
900 pfm_mont_pmc_reg_t reg1, reg2, pmc36;
901 unsigned int i, has_1st_pair, has_2nd_pair, count;
902 unsigned int pos = outp->pfp_pmc_count;
903 int used_pmc32, used_pmc34;
904
905 if (param == NULL) return PFMLIB_SUCCESS;
906
907#define PMC36_DFL_VAL 0xfffffff0
908
909
910 /*
911 * mandatory default value for PMC36 as described in the documentation
912 * all monitoring is opcode constrained. Better make sure the match/mask
913 * is set to match everything! It looks weird for the default value!
914 */
915 pmc36.pmc_val = PMC36_DFL_VAL;
916
917 reg1.pmc_val = 0x030f01ffffffffff;
918 reg2.pmc_val = 0;
919
920 used_pmc32 = param->pfp_mont_opcm1.opcm_used;
921 used_pmc34 = param->pfp_mont_opcm2.opcm_used;
922
923 /*
924 * check in any feature is used.
925 * PMC36 must be setup when opcode matching is used OR when code range restriction is used
926 */
927 if (used_pmc32 == 0 && used_pmc34 == 0 && param->pfp_mont_irange.rr_used == 0)
928 return 0;
929
930 /*
931 * check for rr_nbr_used to make sure that the range request produced something on output
932 */
933 if (used_pmc32 || (param->pfp_mont_irange.rr_used && mod_out->pfp_mont_irange.rr_nbr_used) ) {
934 /*
935 * if not used, ignore all bits
936 */
937 if (used_pmc32) {
943
945 }
946
947 if (param->pfp_mont_irange.rr_used) {
950 } else {
951 /* clear range restriction fields when none is used */
954 }
955
956 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 32))
957 return PFMLIB_ERR_NOASSIGN;
958
959 pc[pos].reg_num = 32;
960 pc[pos].reg_value = reg1.pmc_val;
961 pc[pos].reg_addr = pc[pos].reg_alt_addr = 32;
962 pos++;
963
964 /*
965 * will be constrained by PMC32
966 */
967 if (used_pmc32) {
968 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 33))
969 return PFMLIB_ERR_NOASSIGN;
970 /*
971 * used pmc33 only when we have active opcode matching
972 */
973 pc[pos].reg_num = 33;
974 pc[pos].reg_value = reg2.pmc_val;
975 pc[pos].reg_addr = pc[pos].reg_alt_addr = 33;
976 pos++;
977
978 has_1st_pair = has_2nd_pair = 0;
979 count = inp->pfp_event_count;
980
981 for(i=0; i < count; i++) {
984 }
985 if (has_1st_pair || has_2nd_pair == 0) pmc36.pmc36_mont_reg.opcm_ch0_ig_opcm = 0;
986 if (has_2nd_pair || has_1st_pair == 0) pmc36.pmc36_mont_reg.opcm_ch2_ig_opcm = 0;
987 }
988
989 __pfm_vbprintf("[PMC32(pmc32)=0x%lx m=%d i=%d f=%d b=%d mask=0x%lx inv=%d ig_ad=%d]\n",
990 reg1.pmc_val,
998 if (used_pmc32)
999 __pfm_vbprintf("[PMC33(pmc33)=0x%lx match=0x%lx]\n",
1000 reg2.pmc_val,
1002 }
1003
1004 /*
1005 * will be constrained by PMC34
1006 */
1007 if (used_pmc34) {
1008 reg1.pmc_val = 0x01ffffffffff; /* pmc34 default value */
1009 reg2.pmc_val = 0;
1010
1016
1018
1019 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 34))
1020 return PFMLIB_ERR_NOASSIGN;
1021
1022 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 35))
1023 return PFMLIB_ERR_NOASSIGN;
1024
1025 pc[pos].reg_num = 34;
1026 pc[pos].reg_value = reg1.pmc_val;
1027 pc[pos].reg_addr = pc[pos].reg_alt_addr = 34;
1028 pos++;
1029 pc[pos].reg_num = 35;
1030 pc[pos].reg_value = reg2.pmc_val;
1031 pc[pos].reg_addr = pc[pos].reg_alt_addr = 35;
1032 pos++;
1033
1034 has_1st_pair = has_2nd_pair = 0;
1035 count = inp->pfp_event_count;
1036 for(i=0; i < count; i++) {
1039 }
1040 if (has_1st_pair || has_2nd_pair == 0) pmc36.pmc36_mont_reg.opcm_ch1_ig_opcm = 0;
1041 if (has_2nd_pair || has_1st_pair == 0) pmc36.pmc36_mont_reg.opcm_ch3_ig_opcm = 0;
1042
1043 __pfm_vbprintf("[PMC34(pmc34)=0x%lx m=%d i=%d f=%d b=%d mask=0x%lx]\n",
1044 reg1.pmc_val,
1050
1051 __pfm_vbprintf("[PMC35(pmc35)=0x%lx match=0x%lx]\n",
1052 reg2.pmc_val,
1054
1055 }
1056 if (pmc36.pmc_val != PMC36_DFL_VAL) {
1057
1058 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 36))
1059 return PFMLIB_ERR_NOASSIGN;
1060
1061 pc[pos].reg_num = 36;
1062 pc[pos].reg_value = pmc36.pmc_val;
1063 pc[pos].reg_addr = pc[pos].reg_alt_addr = 36;
1064 pos++;
1065
1066 __pfm_vbprintf("[PMC36(pmc36)=0x%lx ch0_ig_op=%d ch1_ig_op=%d ch2_ig_op=%d ch3_ig_op=%d]\n",
1067 pmc36.pmc_val,
1072 }
1073
1074 outp->pfp_pmc_count = pos;
1075
1076 return PFMLIB_SUCCESS;
1077}
1078
1079static int
1081{
1082 pfmlib_event_t *e= inp->pfp_events;
1084 pfmlib_mont_input_param_t *param = mod_in;
1085 pfmlib_reg_t *pc, *pd;
1086 pfmlib_mont_input_param_t fake_param;
1087 int found_etb = 0, found_bad_dear = 0;
1088 int has_etb_param;
1089 unsigned int i, pos1, pos2;
1090 unsigned int count;
1091
1092 pc = outp->pfp_pmcs;
1093 pd = outp->pfp_pmds;
1094 pos1 = outp->pfp_pmc_count;
1095 pos2 = outp->pfp_pmd_count;
1096 /*
1097 * explicit ETB settings
1098 */
1099 has_etb_param = param && param->pfp_mont_etb.etb_used;
1100
1101 reg.pmc_val = 0UL;
1102
1103 /*
1104 * we need to scan all events looking for DEAR ALAT/TLB due to incompatibility.
1105 * In this case PMC39 must be forced to zero
1106 */
1107 count = inp->pfp_event_count;
1108 for (i=0; i < count; i++) {
1109
1110 if (is_etb(e[i].event)) found_etb = 1;
1111
1112 /*
1113 * keep track of the first ETB event
1114 */
1115
1116 /* look only for DEAR TLB */
1117 if (is_dear(e[i].event) && (is_ear_tlb(e[i].event) || is_ear_alat(e[i].event))) {
1118 found_bad_dear = 1;
1119 }
1120 }
1121
1122 DPRINT("found_etb=%d found_bar_dear=%d\n", found_etb, found_bad_dear);
1123
1124 /*
1125 * did not find D-EAR TLB/ALAT event, need to check param structure
1126 */
1127 if (found_bad_dear == 0 && param && param->pfp_mont_dear.ear_used == 1) {
1130 found_bad_dear = 1;
1131 }
1132
1133 /*
1134 * no explicit ETB event and no special case to deal with (cover part of case 3)
1135 */
1136 if (found_etb == 0 && has_etb_param == 0 && found_bad_dear == 0) return PFMLIB_SUCCESS;
1137
1138 if (has_etb_param == 0) {
1139
1140 /*
1141 * case 3: no ETB event, etb_used=0 but found_bad_dear=1, need to cleanup PMC12
1142 */
1143 if (found_etb == 0) goto assign_zero;
1144
1145 /*
1146 * case 1: we have a ETB event but no param, default setting is to capture
1147 * all branches.
1148 */
1149 memset(&fake_param, 0, sizeof(fake_param));
1150 param = &fake_param;
1151
1152 param->pfp_mont_etb.etb_tm = 0x3; /* all branches */
1153 param->pfp_mont_etb.etb_ptm = 0x3; /* all branches */
1154 param->pfp_mont_etb.etb_ppm = 0x3; /* all branches */
1155 param->pfp_mont_etb.etb_brt = 0x0; /* all branches */
1156
1157 DPRINT("ETB event with no info\n");
1158 }
1159
1160 /*
1161 * case 2: ETB event in the list, param provided
1162 * case 4: no ETB event, param provided (free running mode)
1163 */
1166 reg.pmc39_mont_reg.etbc_ds = 0; /* 1 is reserved */
1167 reg.pmc39_mont_reg.etbc_tm = param->pfp_mont_etb.etb_tm & 0x3;
1168 reg.pmc39_mont_reg.etbc_ptm = param->pfp_mont_etb.etb_ptm & 0x3;
1169 reg.pmc39_mont_reg.etbc_ppm = param->pfp_mont_etb.etb_ppm & 0x3;
1170 reg.pmc39_mont_reg.etbc_brt = param->pfp_mont_etb.etb_brt & 0x3;
1171
1172 /*
1173 * if DEAR-ALAT or DEAR-TLB is set then PMC12 must be set to zero (see documentation p. 87)
1174 *
1175 * D-EAR ALAT/TLB and ETB cannot be used at the same time.
1176 * From documentation: PMC12 must be zero in this mode; else the wrong IP for misses
1177 * coming right after a mispredicted branch.
1178 *
1179 * D-EAR cache is fine.
1180 */
1181assign_zero:
1182 if (found_bad_dear && reg.pmc_val != 0UL) return PFMLIB_ERR_EVTINCOMP;
1183
1184 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 39))
1185 return PFMLIB_ERR_NOASSIGN;
1186
1187 pc[pos1].reg_num = 39;
1188 pc[pos1].reg_value = reg.pmc_val;
1189 pc[pos1].reg_addr = pc[pos1].reg_alt_addr = 39;
1190 pos1++;
1191
1192 __pfm_vbprintf("[PMC39(pmc39)=0x%lx plm=%d pm=%d ds=%d tm=%d ptm=%d ppm=%d brt=%d]\n",
1193 reg.pmc_val,
1201
1202 /*
1203 * only add ETB PMDs when actually using BTB.
1204 * Not needed when dealing with D-EAR TLB and DEAR-ALAT
1205 * PMC39 restriction
1206 */
1207 if (found_etb || has_etb_param) {
1208 pd[pos2].reg_num = 38;
1209 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 38;
1210 pos2++;
1211 pd[pos2].reg_num = 39;
1212 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 39;
1213 pos2++;
1214 __pfm_vbprintf("[PMD38(pmd38)]\n[PMD39(pmd39)\n");
1215
1216
1217 for(i=48; i < 64; i++, pos2++) {
1218 pd[pos2].reg_num = i;
1219 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = i;
1220 __pfm_vbprintf("[PMD%u(pmd%u)]\n", pd[pos2].reg_num, pd[pos2].reg_num);
1221 }
1222 }
1223
1224 /* update final number of entries used */
1225 outp->pfp_pmc_count = pos1;
1226 outp->pfp_pmd_count = pos2;
1227
1228 return PFMLIB_SUCCESS;
1229}
1230
1231static void
1232do_normal_rr(unsigned long start, unsigned long end,
1233 pfmlib_reg_t *br, int nbr, int dir, int *idx, int *reg_idx, int plm)
1234{
1235 unsigned long size, l_addr, c;
1236 unsigned long l_offs = 0, r_offs = 0;
1237 unsigned long l_size, r_size;
1238 dbreg_t db;
1239 int p2;
1240
1241 if (nbr < 1 || end <= start) return;
1242
1243 size = end - start;
1244
1245 DPRINT("start=0x%016lx end=0x%016lx size=0x%lx bytes (%lu bundles) nbr=%d dir=%d\n",
1246 start, end, size, size >> 4, nbr, dir);
1247
1248 p2 = pfm_ia64_fls(size);
1249
1250 c = ALIGN_DOWN(end, p2);
1251
1252 DPRINT("largest power of two possible: 2^%d=0x%lx, crossing=0x%016lx\n",
1253 p2,
1254 1UL << p2, c);
1255
1256 if ((c - (1UL<<p2)) >= start) {
1257 l_addr = c - (1UL << p2);
1258 } else {
1259 p2--;
1260
1261 if ((c + (1UL<<p2)) <= end) {
1262 l_addr = c;
1263 } else {
1264 l_addr = c - (1UL << p2);
1265 }
1266 }
1267 l_size = l_addr - start;
1268 r_size = end - l_addr-(1UL<<p2);
1269
1270 if (PFMLIB_DEBUG()) {
1271 printf("largest chunk: 2^%d=0x%lx @0x%016lx-0x%016lx\n", p2, 1UL<<p2, l_addr, l_addr+(1UL<<p2));
1272 if (l_size) printf("before: 0x%016lx-0x%016lx\n", start, l_addr);
1273 if (r_size) printf("after : 0x%016lx-0x%016lx\n", l_addr+(1UL<<p2), end);
1274 }
1275
1276 if (dir == 0 && l_size != 0 && nbr == 1) {
1277 p2++;
1278 l_addr = end - (1UL << p2);
1279 if (PFMLIB_DEBUG()) {
1280 l_offs = start - l_addr;
1281 printf(">>l_offs: 0x%lx\n", l_offs);
1282 }
1283 } else if (dir == 1 && r_size != 0 && nbr == 1) {
1284 p2++;
1285 l_addr = start;
1286 if (PFMLIB_DEBUG()) {
1287 r_offs = l_addr+(1UL<<p2) - end;
1288 printf(">>r_offs: 0x%lx\n", r_offs);
1289 }
1290 }
1291 l_size = l_addr - start;
1292 r_size = end - l_addr-(1UL<<p2);
1293
1294 if (PFMLIB_DEBUG()) {
1295 printf(">>largest chunk: 2^%d @0x%016lx-0x%016lx\n", p2, l_addr, l_addr+(1UL<<p2));
1296 if (l_size && !l_offs) printf(">>before: 0x%016lx-0x%016lx\n", start, l_addr);
1297 if (r_size && !r_offs) printf(">>after : 0x%016lx-0x%016lx\n", l_addr+(1UL<<p2), end);
1298 }
1299
1300 /*
1301 * we initialize the mask to full 0 and
1302 * only update the mask field. the rest is left
1303 * to zero, except for the plm.
1304 * in the case of ibr, the x-field must be 0. For dbr
1305 * the value of r-field and w-field is ignored.
1306 */
1307
1308 db.val = 0;
1309 db.db.db_mask = ~((1UL << p2)-1);
1310 /*
1311 * we always use default privilege level.
1312 * plm is ignored for DBRs.
1313 */
1314 db.db.db_plm = plm;
1315
1316
1317 br[*idx].reg_num = *reg_idx;
1318 br[*idx].reg_value = l_addr;
1319 br[*idx].reg_addr = br[*idx].reg_alt_addr = *reg_idx;
1320
1321 br[*idx+1].reg_num = *reg_idx+1;
1322 br[*idx+1].reg_value = db.val;
1323 br[*idx+1].reg_addr = br[*idx+1].reg_alt_addr = *reg_idx+1;
1324
1325 *idx += 2;
1326 *reg_idx += 2;
1327
1328 nbr--;
1329 if (nbr) {
1330 int r_nbr, l_nbr;
1331
1332 r_nbr = l_nbr = nbr >>1;
1333
1334 if (nbr & 0x1) {
1335 /*
1336 * our simple heuristic is:
1337 * we assign the largest number of registers to the largest
1338 * of the two chunks
1339 */
1340 if (l_size > r_size) {
1341 l_nbr++;
1342 } else {
1343 r_nbr++;
1344 }
1345
1346 }
1347 do_normal_rr(start, l_addr, br, l_nbr, 0, idx, reg_idx, plm);
1348 do_normal_rr(l_addr+(1UL<<p2), end, br, r_nbr, 1, idx, reg_idx, plm);
1349 }
1350}
1351
1352static void
1353print_one_range(pfmlib_mont_input_rr_desc_t *in_rr, pfmlib_mont_output_rr_desc_t *out_rr, pfmlib_reg_t *dbr, int base_idx, int n_pairs, int fine_mode, unsigned int rr_flags)
1354{
1355 int j;
1356 dbreg_t d;
1357 unsigned long r_end;
1358
1359 __pfm_vbprintf("[0x%lx-0x%lx): %d register pair(s)%s%s\n",
1360 in_rr->rr_start, in_rr->rr_end,
1361 n_pairs,
1362 fine_mode ? ", fine_mode" : "",
1363 rr_flags & PFMLIB_MONT_RR_INV ? ", inversed" : "");
1364
1365 __pfm_vbprintf("start offset: -0x%lx end_offset: +0x%lx\n", out_rr->rr_soff, out_rr->rr_eoff);
1366
1367 for (j=0; j < n_pairs; j++, base_idx+=2) {
1368
1369 d.val = dbr[base_idx+1].reg_value;
1370 r_end = dbr[base_idx].reg_value+((~(d.db.db_mask)) & ~(0xffUL << 56));
1371
1372 if (fine_mode)
1373 __pfm_vbprintf("brp%u: db%u: 0x%016lx db%u: plm=0x%x mask=0x%016lx\n",
1374 dbr[base_idx].reg_num>>1,
1375 dbr[base_idx].reg_num,
1376 dbr[base_idx].reg_value,
1377 dbr[base_idx+1].reg_num,
1378 d.db.db_plm, d.db.db_mask);
1379 else
1380 __pfm_vbprintf("brp%u: db%u: 0x%016lx db%u: plm=0x%x mask=0x%016lx end=0x%016lx\n",
1381 dbr[base_idx].reg_num>>1,
1382 dbr[base_idx].reg_num,
1383 dbr[base_idx].reg_value,
1384 dbr[base_idx+1].reg_num,
1385 d.db.db_plm, d.db.db_mask,
1386 r_end);
1387 }
1388}
1389
1390/*
1391 * base_idx = base register index to use (for IBRP1, base_idx = 2)
1392 */
1393static int
1394compute_fine_rr(pfmlib_mont_input_rr_t *irr, int dfl_plm, int n, int *base_idx, pfmlib_mont_output_rr_t *orr)
1395{
1396 int i;
1397 pfmlib_reg_t *br;
1400 unsigned long addr;
1401 int reg_idx;
1402 dbreg_t db;
1403
1404 in_rr = irr->rr_limits;
1405 out_rr = orr->rr_infos;
1406 br = orr->rr_br+orr->rr_nbr_used;
1407 reg_idx = *base_idx;
1408
1409 db.val = 0;
1411
1412 if (n > 2) return PFMLIB_ERR_IRRTOOMANY;
1413
1414 for (i=0; i < n; i++, reg_idx += 2, in_rr++, br+= 4) {
1415 /*
1416 * setup lower limit pair
1417 *
1418 * because of the PMU can only see addresses on a 2-bundle boundary, we must align
1419 * down to the closest bundle-pair aligned address. 5 => 32-byte aligned address
1420 */
1421 addr = ALIGN_DOWN(in_rr->rr_start, 5);
1422 out_rr->rr_soff = in_rr->rr_start - addr;
1423
1424 /*
1425 * adjust plm for each range
1426 */
1427 db.db.db_plm = in_rr->rr_plm ? in_rr->rr_plm : (unsigned long)dfl_plm;
1428
1429 br[0].reg_num = reg_idx;
1430 br[0].reg_value = addr;
1431 br[0].reg_addr = br[0].reg_alt_addr = 1+reg_idx;
1432 br[1].reg_num = reg_idx+1;
1433 br[1].reg_value = db.val;
1434 br[1].reg_addr = br[1].reg_alt_addr = 1+reg_idx+1;
1435
1436 /*
1437 * setup upper limit pair
1438 *
1439 *
1440 * In fine mode, the bundle address stored in the upper limit debug
1441 * registers is included in the count, so we substract 0x10 to exclude it.
1442 *
1443 * because of the PMU bug, we align the (corrected) end to the nearest
1444 * 32-byte aligned address + 0x10. With this correction and depending
1445 * on the correction, we may count one
1446 *
1447 *
1448 */
1449
1450 addr = in_rr->rr_end - 0x10;
1451
1452 if ((addr & 0x1f) == 0) addr += 0x10;
1453 out_rr->rr_eoff = addr - in_rr->rr_end + 0x10;
1454
1455 br[2].reg_num = reg_idx+4;
1456 br[2].reg_value = addr;
1457 br[2].reg_addr = br[2].reg_alt_addr = 1+reg_idx+4;
1458
1459 br[3].reg_num = reg_idx+5;
1460 br[3].reg_value = db.val;
1461 br[3].reg_addr = br[3].reg_alt_addr = 1+reg_idx+5;
1462
1463 if (PFMLIB_VERBOSE()) print_one_range(in_rr, out_rr, br, 0, 2, 1, irr->rr_flags);
1464 }
1465 orr->rr_nbr_used += i<<2;
1466
1467 /* update base_idx, for subsequent calls */
1468 *base_idx = reg_idx;
1469
1470 return PFMLIB_SUCCESS;
1471}
1472
1473/*
1474 * base_idx = base register index to use (for IBRP1, base_idx = 2)
1475 */
1476static int
1478{
1479 unsigned long size, end, start;
1480 unsigned long p_start, p_end;
1483 pfmlib_reg_t *br;
1484 dbreg_t db;
1485 int reg_idx;
1486 int l, m;
1487
1488 in_rr = irr->rr_limits;
1489 out_rr = orr->rr_infos;
1490 br = orr->rr_br+orr->rr_nbr_used;
1491 start = in_rr->rr_start;
1492 end = in_rr->rr_end;
1493 size = end - start;
1494 reg_idx = *base_idx;
1495
1496 l = pfm_ia64_fls(size);
1497
1498 m = l;
1499 if (size & ((1UL << l)-1)) {
1500 if (l>62) {
1501 printf("range: [0x%lx-0x%lx] too big\n", start, end);
1502 return PFMLIB_ERR_IRRTOOBIG;
1503 }
1504 m++;
1505 }
1506
1507 DPRINT("size=%ld, l=%d m=%d, internal: 0x%lx full: 0x%lx\n",
1508 size,
1509 l, m,
1510 1UL << l,
1511 1UL << m);
1512
1513 for (; m < 64; m++) {
1514 p_start = ALIGN_DOWN(start, m);
1515 p_end = p_start+(1UL<<m);
1516 if (p_end >= end) goto found;
1517 }
1518 return PFMLIB_ERR_IRRINVAL;
1519found:
1520 DPRINT("m=%d p_start=0x%lx p_end=0x%lx\n", m, p_start,p_end);
1521
1522 /* when the event is not IA64_INST_RETIRED, then we MUST use ibrp0 */
1523 br[0].reg_num = reg_idx;
1524 br[0].reg_value = p_start;
1525 br[0].reg_addr = br[0].reg_alt_addr = 1+reg_idx;
1526
1527 db.val = 0;
1528 db.db.db_mask = ~((1UL << m)-1);
1529 db.db.db_plm = in_rr->rr_plm ? in_rr->rr_plm : (unsigned long)dfl_plm;
1530
1531
1532 br[1].reg_num = reg_idx + 1;
1533 br[1].reg_value = db.val;
1534 br[1].reg_addr = br[1].reg_alt_addr = 1+reg_idx+1;
1535
1536 out_rr->rr_soff = start - p_start;
1537 out_rr->rr_eoff = p_end - end;
1538
1539 if (PFMLIB_VERBOSE()) print_one_range(in_rr, out_rr, br, 0, 1, 0, irr->rr_flags);
1540
1541 orr->rr_nbr_used += 2;
1542
1543 /* update base_idx, for subsequent calls */
1544 *base_idx = reg_idx;
1545
1546 return PFMLIB_SUCCESS;
1547}
1548
1549static int
1550compute_normal_rr(pfmlib_mont_input_rr_t *irr, int dfl_plm, int n, int *base_idx, pfmlib_mont_output_rr_t *orr)
1551{
1554 unsigned long r_end;
1555 pfmlib_reg_t *br;
1556 dbreg_t d;
1557 int i, j;
1558 int br_index, reg_idx, prev_index;
1559
1560 in_rr = irr->rr_limits;
1561 out_rr = orr->rr_infos;
1562 br = orr->rr_br+orr->rr_nbr_used;
1563 reg_idx = *base_idx;
1564 br_index = 0;
1565
1566 for (i=0; i < n; i++, in_rr++, out_rr++) {
1567 /*
1568 * running out of registers
1569 */
1570 if (br_index == 8) break;
1571
1572 prev_index = br_index;
1573
1574 do_normal_rr( in_rr->rr_start,
1575 in_rr->rr_end,
1576 br,
1577 4 - (reg_idx>>1), /* how many pairs available */
1578 0,
1579 &br_index,
1580 &reg_idx, in_rr->rr_plm ? in_rr->rr_plm : dfl_plm);
1581
1582 DPRINT("br_index=%d reg_idx=%d\n", br_index, reg_idx);
1583
1584 /*
1585 * compute offsets
1586 */
1587 out_rr->rr_soff = out_rr->rr_eoff = 0;
1588
1589 for(j=prev_index; j < br_index; j+=2) {
1590
1591 d.val = br[j+1].reg_value;
1592 r_end = br[j].reg_value+((~(d.db.db_mask)+1) & ~(0xffUL << 56));
1593
1594 if (br[j].reg_value <= in_rr->rr_start)
1595 out_rr->rr_soff = in_rr->rr_start - br[j].reg_value;
1596
1597 if (r_end >= in_rr->rr_end)
1598 out_rr->rr_eoff = r_end - in_rr->rr_end;
1599 }
1600
1601 if (PFMLIB_VERBOSE()) print_one_range(in_rr, out_rr, br, prev_index, (br_index-prev_index)>>1, 0, irr->rr_flags);
1602 }
1603
1604 /* do not have enough registers to cover all the ranges */
1605 if (br_index == 8 && i < n) return PFMLIB_ERR_TOOMANY;
1606
1607 orr->rr_nbr_used += br_index;
1608
1609 /* update base_idx, for subsequent calls */
1610 *base_idx = reg_idx;
1611
1612 return PFMLIB_SUCCESS;
1613}
1614
1615
1616static int
1618{
1620 pfmlib_mont_input_param_t *param = mod_in;
1623 pfmlib_reg_t *pc = outp->pfp_pmcs;
1624 unsigned long retired_mask;
1625 unsigned int i, pos = outp->pfp_pmc_count, count;
1626 unsigned int retired_only, retired_count, fine_mode, prefetch_count;
1627 unsigned int n_intervals;
1628 int base_idx = 0, dup = 0;
1629 int ret;
1630
1631 if (param == NULL) return PFMLIB_SUCCESS;
1632
1633 if (param->pfp_mont_irange.rr_used == 0) return PFMLIB_SUCCESS;
1634
1635 if (mod_out == NULL) return PFMLIB_ERR_INVAL;
1636
1637 irr = &param->pfp_mont_irange;
1638 orr = &mod_out->pfp_mont_irange;
1639
1640 ret = check_intervals(irr, 0, &n_intervals);
1641 if (ret != PFMLIB_SUCCESS) return ret;
1642
1643 if (n_intervals < 1) return PFMLIB_ERR_IRRINVAL;
1644
1645
1646 retired_count = check_inst_retired_events(inp, &retired_mask);
1647 retired_only = retired_count == inp->pfp_event_count;
1648 fine_mode = irr->rr_flags & PFMLIB_MONT_RR_NO_FINE_MODE ?
1649 0 : check_fine_mode_possible(irr, n_intervals);
1650
1651
1652 DPRINT("n_intervals=%d retired_only=%d retired_count=%d fine_mode=%d\n",
1653 n_intervals, retired_only, retired_count, fine_mode);
1654 /*
1655 * On montecito, there are more constraints on what can be measured with irange.
1656 *
1657 * - The fine mode is the best because you directly set the lower and upper limits of
1658 * the range. This uses 2 ibr pairs for range (ibrp0/ibrp2 and ibp1/ibrp3). Therefore
1659 * at most 2 fine mode ranges can be defined. The boundaries of the range must be in the
1660 * same 64KB page. The fine mode works will all events.
1661 *
1662 * - if the fine mode fails, then for all events, except IA64_TAGGED_INST_RETIRED_*, only
1663 * the first pair of ibr is available: ibrp0. This imposes some severe restrictions on the
1664 * size and alignement of the range. It can be bigger than 64KB and must be properly aligned
1665 * on its size. The library relaxes these constraints by allowing the covered areas to be
1666 * larger than the expected range. It may start before and end after the requested range.
1667 * You can determine the amount of overrun in either direction for each range by looking at
1668 * the rr_soff (start offset) and rr_eoff (end offset).
1669 *
1670 * - if the events include certain prefetch events then only IBRP1 can be used.
1671 * See 3.3.5.2 Exception 1.
1672 *
1673 * - Finally, when the events are ONLY IA64_TAGGED_INST_RETIRED_* then all IBR pairs can be used
1674 * to cover the range giving us more flexibility to approximate the range when it is not
1675 * properly aligned on its size (see 10.3.5.2 Exception 2). But the corresponding
1676 * IA64_TAGGED_INST_RETIRED_* must be present.
1677 */
1678
1679 if (fine_mode == 0 && retired_only == 0 && n_intervals > 1) return PFMLIB_ERR_IRRTOOMANY;
1680
1681 /* we do not default to non-fine mode to support more ranges */
1682 if (n_intervals > 2 && fine_mode == 1) return PFMLIB_ERR_IRRTOOMANY;
1683
1684 ret = check_prefetch_events(inp, irr, &prefetch_count, &base_idx, &dup);
1685 if (ret)
1686 return ret;
1687
1688 DPRINT("prefetch_count=%u base_idx=%d dup=%d\n", prefetch_count, base_idx, dup);
1689
1690 /*
1691 * CPU_OP_CYCLES.QUAL supports code range restrictions but it returns
1692 * meaningful values (fine/coarse mode) only when IBRP1 is not used.
1693 */
1694 if ((base_idx > 0 || dup) && has_cpu_cycles_qual(inp))
1695 return PFMLIB_ERR_FEATCOMB;
1696
1697 if (fine_mode == 0) {
1698 if (retired_only) {
1699 /* can take multiple intervals */
1700 ret = compute_normal_rr(irr, inp->pfp_dfl_plm, n_intervals, &base_idx, orr);
1701 } else {
1702 /* unless we have only prefetch and instruction retired events,
1703 * we cannot satisfy the request because the other events cannot
1704 * be measured on anything but IBRP0.
1705 */
1706 if ((prefetch_count+retired_count) != inp->pfp_event_count)
1707 return PFMLIB_ERR_FEATCOMB;
1708
1709 ret = compute_single_rr(irr, inp->pfp_dfl_plm, &base_idx, orr);
1710 if (ret == PFMLIB_SUCCESS && dup)
1711 ret = compute_single_rr(irr, inp->pfp_dfl_plm, &base_idx, orr);
1712 }
1713 } else {
1714 if (prefetch_count && n_intervals != 1) return PFMLIB_ERR_IRRTOOMANY;
1715
1716 /* except is retired_only, can take only one interval */
1717 ret = compute_fine_rr(irr, inp->pfp_dfl_plm, n_intervals, &base_idx, orr);
1718
1719 if (ret == PFMLIB_SUCCESS && dup)
1720 ret = compute_fine_rr(irr, inp->pfp_dfl_plm, n_intervals, &base_idx, orr);
1721 }
1722
1723 if (ret != PFMLIB_SUCCESS)
1724 return ret == PFMLIB_ERR_TOOMANY ? PFMLIB_ERR_IRRTOOMANY : ret;
1725
1726 reg.pmc_val = 0xdb6; /* default value */
1727
1728 count = orr->rr_nbr_used;
1729 for (i=0; i < count; i++) {
1730 switch(orr->rr_br[i].reg_num) {
1731 case 0:
1733 break;
1734 case 2:
1736 break;
1737 case 4:
1739 break;
1740 case 6:
1742 break;
1743 }
1744 }
1745
1746 if (fine_mode) {
1747 reg.pmc38_mont_reg.iarc_fine = 1;
1748 } else if (retired_only) {
1749 /*
1750 * we need to check that the user provided all the events needed to cover
1751 * all the ibr pairs used to cover the range
1752 */
1753 if ((retired_mask & 0x1) == 0 && reg.pmc38_mont_reg.iarc_ig_ibrp0 == 0) return PFMLIB_ERR_IRRINVAL;
1754 if ((retired_mask & 0x2) == 0 && reg.pmc38_mont_reg.iarc_ig_ibrp1 == 0) return PFMLIB_ERR_IRRINVAL;
1755 if ((retired_mask & 0x4) == 0 && reg.pmc38_mont_reg.iarc_ig_ibrp2 == 0) return PFMLIB_ERR_IRRINVAL;
1756 if ((retired_mask & 0x8) == 0 && reg.pmc38_mont_reg.iarc_ig_ibrp3 == 0) return PFMLIB_ERR_IRRINVAL;
1757 }
1758
1759 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 38))
1760 return PFMLIB_ERR_NOASSIGN;
1761
1762 pc[pos].reg_num = 38;
1763 pc[pos].reg_value = reg.pmc_val;
1764 pc[pos].reg_addr = pc[pos].reg_alt_addr = 38;
1765 pos++;
1766
1767 __pfm_vbprintf("[PMC38(pmc38)=0x%lx ig_ibrp0=%d ig_ibrp1=%d ig_ibrp2=%d ig_ibrp3=%d fine=%d]\n",
1768 reg.pmc_val,
1774
1775 outp->pfp_pmc_count = pos;
1776
1777 return PFMLIB_SUCCESS;
1778}
1779
1780static const unsigned long iod_tab[8]={
1781 /* --- */ 3,
1782 /* --D */ 2,
1783 /* -O- */ 3, /* should not be used */
1784 /* -OD */ 0, /* =IOD safe because default IBR is harmless */
1785 /* I-- */ 1, /* =IO safe because by defaut OPC is turned off */
1786 /* I-D */ 0, /* =IOD safe because by default opc is turned off */
1787 /* IO- */ 1,
1788 /* IOD */ 0
1789};
1790
1791/*
1792 * IMPORTANT: MUST BE CALLED *AFTER* pfm_dispatch_irange() to make sure we see
1793 * the irange programming to adjust pmc41.
1794 */
1795static int
1797{
1798 pfmlib_mont_input_param_t *param = mod_in;
1799 pfmlib_reg_t *pc = outp->pfp_pmcs;
1801 pfmlib_mont_output_rr_t *orr, *orr2;
1802 pfm_mont_pmc_reg_t pmc38;
1804 unsigned int i, pos = outp->pfp_pmc_count;
1805 int iod_codes[4], dfl_val_pmc32, dfl_val_pmc34;
1806 unsigned int n_intervals;
1807 int ret;
1808 int base_idx = 0;
1809 int fine_mode = 0;
1810#define DR_USED 0x1 /* data range is used */
1811#define OP_USED 0x2 /* opcode matching is used */
1812#define IR_USED 0x4 /* code range is used */
1813
1814 if (param == NULL) return PFMLIB_SUCCESS;
1815 /*
1816 * if only pmc32/pmc33 opcode matching is used, we do not need to change
1817 * the default value of pmc41 regardless of the events being measured.
1818 */
1819 if ( param->pfp_mont_drange.rr_used == 0
1820 && param->pfp_mont_irange.rr_used == 0) return PFMLIB_SUCCESS;
1821
1822 /*
1823 * it seems like the ignored bits need to have special values
1824 * otherwise this does not work.
1825 */
1826 reg.pmc_val = 0x2078fefefefe;
1827
1828 /*
1829 * initialize iod codes
1830 */
1831 iod_codes[0] = iod_codes[1] = iod_codes[2] = iod_codes[3] = 0;
1832
1833 /*
1834 * setup default iod value, we need to separate because
1835 * if drange is used we do not know in advance which DBR will be used
1836 * therefore we need to apply dfl_val later
1837 */
1838 dfl_val_pmc32 = param->pfp_mont_opcm1.opcm_used ? OP_USED : 0;
1839 dfl_val_pmc34 = param->pfp_mont_opcm2.opcm_used ? OP_USED : 0;
1840
1841 if (param->pfp_mont_drange.rr_used == 1) {
1842
1843 if (mod_out == NULL) return PFMLIB_ERR_INVAL;
1844
1845 irr = &param->pfp_mont_drange;
1846 orr = &mod_out->pfp_mont_drange;
1847
1848 ret = check_intervals(irr, 1, &n_intervals);
1849 if (ret != PFMLIB_SUCCESS) return ret;
1850
1851 if (n_intervals < 1) return PFMLIB_ERR_DRRINVAL;
1852
1853 ret = compute_normal_rr(irr, inp->pfp_dfl_plm, n_intervals, &base_idx, orr);
1854 if (ret != PFMLIB_SUCCESS) {
1855 return ret == PFMLIB_ERR_TOOMANY ? PFMLIB_ERR_DRRTOOMANY : ret;
1856 }
1857
1858 /*
1859 * Update iod_codes to reflect the use of the DBR constraint.
1860 */
1861 for (i=0; i < orr->rr_nbr_used; i++) {
1862 if (orr->rr_br[i].reg_num == 0) iod_codes[0] |= DR_USED | dfl_val_pmc32;
1863 if (orr->rr_br[i].reg_num == 2) iod_codes[1] |= DR_USED | dfl_val_pmc34;
1864 if (orr->rr_br[i].reg_num == 4) iod_codes[2] |= DR_USED | dfl_val_pmc32;
1865 if (orr->rr_br[i].reg_num == 6) iod_codes[3] |= DR_USED | dfl_val_pmc34;
1866 }
1867
1868 }
1869
1870 /*
1871 * XXX: assume dispatch_irange executed before calling this function
1872 */
1873 if (param->pfp_mont_irange.rr_used == 1) {
1874
1875 orr2 = &mod_out->pfp_mont_irange;
1876
1877 if (mod_out == NULL) return PFMLIB_ERR_INVAL;
1878
1879 /*
1880 * we need to find out whether or not the irange is using
1881 * fine mode. If this is the case, then we only need to
1882 * program pmc41 for the ibr pairs which designate the lower
1883 * bounds of a range. For instance, if IBRP0/IBRP2 are used,
1884 * then we only need to program pmc13.cfg_dbrp0 and pmc13.ena_dbrp0,
1885 * the PMU will automatically use IBRP2, even though pmc13.ena_dbrp2=0.
1886 */
1887 for(i=0; i <= pos; i++) {
1888 if (pc[i].reg_num == 38) {
1889 pmc38.pmc_val = pc[i].reg_value;
1890 if (pmc38.pmc38_mont_reg.iarc_fine == 1) fine_mode = 1;
1891 break;
1892 }
1893 }
1894
1895 /*
1896 * Update to reflect the use of the IBR constraint
1897 */
1898 for (i=0; i < orr2->rr_nbr_used; i++) {
1899 if (orr2->rr_br[i].reg_num == 0) iod_codes[0] |= IR_USED | dfl_val_pmc32;
1900 if (orr2->rr_br[i].reg_num == 2) iod_codes[1] |= IR_USED | dfl_val_pmc34;
1901 if (fine_mode == 0 && orr2->rr_br[i].reg_num == 4) iod_codes[2] |= IR_USED | dfl_val_pmc32;
1902 if (fine_mode == 0 && orr2->rr_br[i].reg_num == 6) iod_codes[3] |= IR_USED | dfl_val_pmc34;
1903 }
1904 }
1905
1906 if (param->pfp_mont_irange.rr_used == 0 && param->pfp_mont_drange.rr_used ==0) {
1907 iod_codes[0] = iod_codes[2] = dfl_val_pmc32;
1908 iod_codes[1] = iod_codes[3] = dfl_val_pmc34;
1909 }
1910
1911 /*
1912 * update the cfg dbrpX field. If we put a constraint on a cfg dbrp, then
1913 * we must enable it in the corresponding ena_dbrpX
1914 */
1915 reg.pmc41_mont_reg.darc_ena_dbrp0 = iod_codes[0] ? 1 : 0;
1916 reg.pmc41_mont_reg.darc_cfg_dtag0 = iod_tab[iod_codes[0]];
1917
1918 reg.pmc41_mont_reg.darc_ena_dbrp1 = iod_codes[1] ? 1 : 0;
1919 reg.pmc41_mont_reg.darc_cfg_dtag1 = iod_tab[iod_codes[1]];
1920
1921 reg.pmc41_mont_reg.darc_ena_dbrp2 = iod_codes[2] ? 1 : 0;
1922 reg.pmc41_mont_reg.darc_cfg_dtag2 = iod_tab[iod_codes[2]];
1923
1924 reg.pmc41_mont_reg.darc_ena_dbrp3 = iod_codes[3] ? 1 : 0;
1925 reg.pmc41_mont_reg.darc_cfg_dtag3 = iod_tab[iod_codes[3]];
1926
1927 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 41))
1928 return PFMLIB_ERR_NOASSIGN;
1929
1930 pc[pos].reg_num = 41;
1931 pc[pos].reg_value = reg.pmc_val;
1932 pc[pos].reg_addr = pc[pos].reg_alt_addr = 41;
1933 pos++;
1934
1935 __pfm_vbprintf("[PMC41(pmc41)=0x%lx cfg_dtag0=%d cfg_dtag1=%d cfg_dtag2=%d cfg_dtag3=%d ena_dbrp0=%d ena_dbrp1=%d ena_dbrp2=%d ena_dbrp3=%d]\n",
1936 reg.pmc_val,
1945
1946 outp->pfp_pmc_count = pos;
1947
1948 return PFMLIB_SUCCESS;
1949}
1950
1951static int
1953{
1954 pfmlib_mont_input_param_t *param = mod_in;
1955 pfmlib_event_t *e = inp->pfp_events;
1956 unsigned int i, count;
1957
1958
1959 count = inp->pfp_event_count;
1960 for(i=0; i < count; i++) {
1961 /*
1962 * skip check for counter which requested it. Use at your own risk.
1963 * No all counters have necessarily been validated for use with
1964 * qualifiers. Typically the event is counted as if no constraint
1965 * existed.
1966 */
1968
1969
1970 if (evt_use_irange(param) && has_iarr(e[i].event) == 0) return PFMLIB_ERR_FEATCOMB;
1971 if (evt_use_drange(param) && has_darr(e[i].event) == 0) return PFMLIB_ERR_FEATCOMB;
1972 if (evt_use_opcm(param) && has_opcm(e[i].event) == 0) return PFMLIB_ERR_FEATCOMB;
1973 }
1974 return PFMLIB_SUCCESS;
1975}
1976
1977static int
1979{
1980 pfmlib_mont_input_param_t *param = mod_in;
1981 unsigned int i, count;
1982
1983 if (param->pfp_mont_drange.rr_used == 0 && param->pfp_mont_irange.rr_used == 0) return PFMLIB_SUCCESS;
1984
1985 /*
1986 * range restriction applies to all events, therefore we must have a consistent
1987 * set of plm and they must match the pfp_dfl_plm which is used to setup the debug
1988 * registers
1989 */
1990 count = inp->pfp_event_count;
1991 for(i=0; i < count; i++) {
1992 if (inp->pfp_events[i].plm && inp->pfp_events[i].plm != inp->pfp_dfl_plm) return PFMLIB_ERR_FEATCOMB;
1993 }
1994 return PFMLIB_SUCCESS;
1995}
1996
1997static int
1999{
2001 pfmlib_mont_input_param_t *param = mod_in;
2002 pfmlib_event_t *e = inp->pfp_events;
2003 pfmlib_reg_t *pc, *pd;
2004 unsigned int pos1, pos2;
2005 unsigned int i, count;
2006
2007 pc = outp->pfp_pmcs;
2008 pd = outp->pfp_pmds;
2009 pos1 = outp->pfp_pmc_count;
2010 pos2 = outp->pfp_pmd_count;
2011 /*
2012 * check if there is something to do
2013 */
2014 if (param == NULL || param->pfp_mont_ipear.ipear_used == 0) return PFMLIB_SUCCESS;
2015
2016 /*
2017 * we need to look for use of ETB, because IP-EAR and ETB cannot be used at the
2018 * same time
2019 */
2020 if (param->pfp_mont_etb.etb_used) return PFMLIB_ERR_FEATCOMB;
2021
2022 /*
2023 * look for implicit ETB used because of BRANCH_EVENT
2024 */
2025 count = inp->pfp_event_count;
2026 for (i=0; i < count; i++) {
2027 if (is_etb(e[i].event)) return PFMLIB_ERR_FEATCOMB;
2028 }
2029 reg.pmc_val = 0;
2030
2033 reg.pmc42_mont_reg.ipear_mode = 4;
2035
2036 if (pfm_regmask_isset(&inp->pfp_unavail_pmcs, 42))
2037 return PFMLIB_ERR_NOASSIGN;
2038
2039 pc[pos1].reg_num = 42;
2040 pc[pos1].reg_value = reg.pmc_val;
2041 pc[pos1].reg_addr = pc[pos1].reg_alt_addr = 42;
2042 pos1++;
2043
2044 __pfm_vbprintf("[PMC42(pmc42)=0x%lx plm=%d pm=%d mode=%d delay=%d]\n",
2045 reg.pmc_val,
2050
2051 pd[pos2].reg_num = 38;
2052 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 38;
2053 pos2++;
2054 pd[pos2].reg_num = 39;
2055 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = 39;
2056 pos2++;
2057 __pfm_vbprintf("[PMD38(pmd38)]\n[PMD39(pmd39)\n");
2058
2059 for(i=48; i < 64; i++, pos2++) {
2060 pd[pos2].reg_num = i;
2061 pd[pos2].reg_addr = pd[pos2].reg_alt_addr = i;
2062 __pfm_vbprintf("[PMD%u(pmd%u)]\n", pd[pos2].reg_num, pd[pos2].reg_num);
2063 }
2064
2065 outp->pfp_pmc_count = pos1;
2066 outp->pfp_pmd_count = pos2;
2067
2068 return PFMLIB_SUCCESS;
2069}
2070
2071static int
2072pfm_mont_dispatch_events(pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
2073{
2074 int ret;
2077
2078 /*
2079 * nothing will come out of this combination
2080 */
2081 if (mod_out && mod_in == NULL) return PFMLIB_ERR_INVAL;
2082
2083 /* check opcode match, range restriction qualifiers */
2084 if (mod_in && check_qualifier_constraints(inp, mod_in) != PFMLIB_SUCCESS) return PFMLIB_ERR_FEATCOMB;
2085
2086 /* check for problems with range restriction and per-event plm */
2087 if (mod_in && check_range_plm(inp, mod_in) != PFMLIB_SUCCESS) return PFMLIB_ERR_FEATCOMB;
2088
2089 ret = pfm_mont_dispatch_counters(inp, mod_in, outp);
2090 if (ret != PFMLIB_SUCCESS) return ret;
2091
2092 /* now check for I-EAR */
2093 ret = pfm_dispatch_iear(inp, mod_in, outp);
2094 if (ret != PFMLIB_SUCCESS) return ret;
2095
2096 /* now check for D-EAR */
2097 ret = pfm_dispatch_dear(inp, mod_in, outp);
2098 if (ret != PFMLIB_SUCCESS) return ret;
2099
2100 /* XXX: must be done before dispatch_opcm() and dispatch_drange() */
2101 ret = pfm_dispatch_irange(inp, mod_in, outp, mod_out);;
2102 if (ret != PFMLIB_SUCCESS) return ret;
2103
2104 ret = pfm_dispatch_drange(inp, mod_in, outp, mod_out);;
2105 if (ret != PFMLIB_SUCCESS) return ret;
2106
2107 /* now check for Opcode matchers */
2108 ret = pfm_dispatch_opcm(inp, mod_in, outp, mod_out);
2109 if (ret != PFMLIB_SUCCESS) return ret;
2110
2111 /* now check for ETB */
2112 ret = pfm_dispatch_etb(inp, mod_in, outp);
2113 if (ret != PFMLIB_SUCCESS) return ret;
2114
2115 /* now check for IP-EAR */
2116 ret = pfm_dispatch_ipear(inp, mod_in, outp);
2117
2118 return ret;
2119}
2120
2121
2122/* XXX: return value is also error code */
2123int
2124pfm_mont_get_event_maxincr(unsigned int i, unsigned int *maxincr)
2125{
2126 if (i >= PME_MONT_EVENT_COUNT || maxincr == NULL) return PFMLIB_ERR_INVAL;
2127 *maxincr = montecito_pe[i].pme_maxincr;
2128 return PFMLIB_SUCCESS;
2129}
2130
2131int
2132pfm_mont_is_ear(unsigned int i)
2133{
2134 return i < PME_MONT_EVENT_COUNT && is_ear(i);
2135}
2136
2137int
2138pfm_mont_is_dear(unsigned int i)
2139{
2140 return i < PME_MONT_EVENT_COUNT && is_dear(i);
2141}
2142
2143int
2145{
2146 return i < PME_MONT_EVENT_COUNT && is_dear(i) && is_ear_tlb(i);
2147}
2148
2149int
2151{
2152 return i < PME_MONT_EVENT_COUNT && is_dear(i) && is_ear_cache(i);
2153}
2154
2155int
2157{
2158 return i < PME_MONT_EVENT_COUNT && is_ear_alat(i);
2159}
2160
2161int
2162pfm_mont_is_iear(unsigned int i)
2163{
2164 return i < PME_MONT_EVENT_COUNT && is_iear(i);
2165}
2166
2167int
2169{
2170 return i < PME_MONT_EVENT_COUNT && is_iear(i) && is_ear_tlb(i);
2171}
2172
2173int
2175{
2176 return i < PME_MONT_EVENT_COUNT && is_iear(i) && is_ear_cache(i);
2177}
2178
2179int
2180pfm_mont_is_etb(unsigned int i)
2181{
2182 return i < PME_MONT_EVENT_COUNT && is_etb(i);
2183}
2184
2185int
2187{
2188 return i < PME_MONT_EVENT_COUNT && has_iarr(i);
2189}
2190
2191
2192int
2194{
2195 return i < PME_MONT_EVENT_COUNT && has_darr(i);
2196}
2197
2198
2199int
2201{
2202 return i < PME_MONT_EVENT_COUNT && has_opcm(i);
2203}
2204
2205int
2207{
2208 return i < PME_MONT_EVENT_COUNT && has_all(i);
2209}
2210
2211
2212int
2214{
2216
2217 if (!is_ear(i) || m == NULL) return PFMLIB_ERR_INVAL;
2218
2220 if (is_ear_tlb(i)) goto done;
2221
2223 if (is_ear_cache(i)) goto done;
2224
2226 if (is_ear_alat(i)) goto done;
2227
2228 return PFMLIB_ERR_INVAL;
2229done:
2230 *m = r;
2231 return PFMLIB_SUCCESS;
2232}
2233
2234static int
2235pfm_mont_get_event_code(unsigned int i, unsigned int cnt, int *code)
2236{
2237 if (cnt != PFMLIB_CNT_FIRST && (cnt < 4 || cnt > 15))
2238 return PFMLIB_ERR_INVAL;
2239
2240 *code = (int)montecito_pe[i].pme_code;
2241
2242 return PFMLIB_SUCCESS;
2243}
2244
2245/*
2246 * This function is accessible directly to the user
2247 */
2248int
2249pfm_mont_get_event_umask(unsigned int i, unsigned long *umask)
2250{
2251 if (i >= PME_MONT_EVENT_COUNT || umask == NULL) return PFMLIB_ERR_INVAL;
2252 *umask = evt_umask(i);
2253 return PFMLIB_SUCCESS;
2254}
2255
2256int
2257pfm_mont_get_event_group(unsigned int i, int *grp)
2258{
2259 if (i >= PME_MONT_EVENT_COUNT || grp == NULL) return PFMLIB_ERR_INVAL;
2260 *grp = evt_grp(i);
2261 return PFMLIB_SUCCESS;
2262}
2263
2264int
2265pfm_mont_get_event_set(unsigned int i, int *set)
2266{
2267 if (i >= PME_MONT_EVENT_COUNT || set == NULL) return PFMLIB_ERR_INVAL;
2268 *set = evt_set(i) == 0xf ? PFMLIB_MONT_EVT_NO_SET : evt_set(i);
2269 return PFMLIB_SUCCESS;
2270}
2271
2272int
2273pfm_mont_get_event_type(unsigned int i, int *type)
2274{
2275 if (i >= PME_MONT_EVENT_COUNT || type == NULL) return PFMLIB_ERR_INVAL;
2276 *type = evt_caf(i);
2277 return PFMLIB_SUCCESS;
2278}
2279
2280/* external interface */
2281int
2283{
2284 pfmlib_mont_output_param_t *param = mod_out;
2286 unsigned int i, count;
2287
2288 /* some sanity checks */
2289 if (outp == NULL || param == NULL) return 0;
2290 if (outp->pfp_pmc_count >= PFMLIB_MAX_PMCS) return 0;
2291
2292 if (param->pfp_mont_irange.rr_nbr_used == 0) return 0;
2293
2294 /*
2295 * we look for pmc38 as it contains the bit indicating if fine mode is used
2296 */
2297 count = outp->pfp_pmc_count;
2298 for(i=0; i < count; i++) {
2299 if (outp->pfp_pmcs[i].reg_num == 38) goto found;
2300 }
2301 return 0;
2302found:
2303 reg.pmc_val = outp->pfp_pmcs[i].reg_value;
2304 return reg.pmc38_mont_reg.iarc_fine ? 1 : 0;
2305}
2306
2307static char *
2309{
2310 return montecito_pe[i].pme_name;
2311}
2312
2313static void
2315{
2316 unsigned int i;
2317 unsigned long m;
2318
2319 memset(counters, 0, sizeof(*counters));
2320
2322 for(i=0; m ; i++, m>>=1) {
2323 if (m & 0x1)
2324 pfm_regmask_set(counters, i);
2325 }
2326}
2327
2328static void
2330{
2331 unsigned int i = 0;
2332
2333 for(i=0; i < 16; i++)
2334 pfm_regmask_set(impl_pmcs, i);
2335
2336 for(i=32; i < 43; i++)
2337 pfm_regmask_set(impl_pmcs, i);
2338}
2339
2340static void
2342{
2343 unsigned int i = 0;
2344
2345 for(i=4; i < 16; i++)
2346 pfm_regmask_set(impl_pmds, i);
2347 for(i=32; i < 40; i++)
2348 pfm_regmask_set(impl_pmds, i);
2349 for(i=48; i < 64; i++)
2350 pfm_regmask_set(impl_pmds, i);
2351}
2352
2353static void
2355{
2356 unsigned int i = 0;
2357
2358 /* counter pmds are contiguous */
2359 for(i=4; i < 16; i++)
2360 pfm_regmask_set(impl_counters, i);
2361}
2362
2363static void
2365{
2366 *width = PMU_MONT_COUNTER_WIDTH;
2367}
2368
2369static int
2370pfm_mont_get_event_description(unsigned int ev, char **str)
2371{
2372 char *s;
2373 s = montecito_pe[ev].pme_desc;
2374 if (s) {
2375 *str = strdup(s);
2376 } else {
2377 *str = NULL;
2378 }
2379 return PFMLIB_SUCCESS;
2380}
2381
2382static int
2384{
2386 return PFMLIB_SUCCESS;
2387
2388}
2389
2390static int
2392{
2394 return PFMLIB_SUCCESS;
2395}
2396
2397static unsigned int
2399{
2400 return has_mesi(event) ? 4 : 0;
2401}
2402
2403static char *
2404pfm_mont_get_event_mask_name(unsigned int event, unsigned int mask)
2405{
2406 switch(mask) {
2407 case 0: return "I";
2408 case 1: return "S";
2409 case 2: return "E";
2410 case 3: return "M";
2411 }
2412 return NULL;
2413}
2414
2415static int
2416pfm_mont_get_event_mask_desc(unsigned int event, unsigned int mask, char **desc)
2417{
2418 switch(mask) {
2419 case 0: *desc = strdup("invalid");
2420 break;
2421 case 1: *desc = strdup("shared");
2422 break;
2423 case 2: *desc = strdup("exclusive");
2424 break;
2425 case 3: *desc = strdup("modified");
2426 break;
2427 default:
2428 return PFMLIB_ERR_INVAL;
2429 }
2430 return PFMLIB_SUCCESS;
2431}
2432
2433static int
2435 unsigned int mask, unsigned int *code)
2436{
2437 *code = mask;
2438 return PFMLIB_SUCCESS;
2439}
2440
2442 .pmu_name = "dual-core Itanium 2",
2443 .pmu_type = PFMLIB_MONTECITO_PMU,
2444 .pme_count = PME_MONT_EVENT_COUNT,
2445 .pmc_count = PMU_MONT_NUM_PMCS,
2446 .pmd_count = PMU_MONT_NUM_PMDS,
2447 .num_cnt = PMU_MONT_NUM_COUNTERS,
2448 .get_event_code = pfm_mont_get_event_code,
2449 .get_event_name = pfm_mont_get_event_name,
2450 .get_event_counters = pfm_mont_get_event_counters,
2451 .dispatch_events = pfm_mont_dispatch_events,
2452 .pmu_detect = pfm_mont_detect,
2453 .get_impl_pmcs = pfm_mont_get_impl_pmcs,
2454 .get_impl_pmds = pfm_mont_get_impl_pmds,
2455 .get_impl_counters = pfm_mont_get_impl_counters,
2456 .get_hw_counter_width = pfm_mont_get_hw_counter_width,
2457 .get_event_desc = pfm_mont_get_event_description,
2458 .get_cycle_event = pfm_mont_get_cycle_event,
2459 .get_inst_retired_event = pfm_mont_get_inst_retired,
2460 .get_num_event_masks = pfm_mont_get_num_event_masks,
2461 .get_event_mask_name = pfm_mont_get_event_mask_name,
2462 .get_event_mask_desc = pfm_mont_get_event_mask_desc,
2463 .get_event_mask_code = pfm_mont_get_event_mask_code
2464};
double tmp
int i
double s2
Definition: byte_profile.c:36
double s
Definition: byte_profile.c:36
static long count
static struct timeval start
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
uint16_t type
#define PME_MONT_CPU_OP_CYCLES_QUAL
#define PME_MONT_IA64_INST_RETIRED
static pme_mont_entry_t montecito_pe[]
#define PME_MONT_IA64_TAGGED_INST_RETIRED_IBRP1_PMC34_35
#define PME_MONT_L2D_OZQ_CANCELS0_ACQ
#define PME_MONT_IA64_TAGGED_INST_RETIRED_IBRP3_PMC34_35
#define PME_MONT_EVENT_COUNT
#define PME_MONT_CPU_OP_CYCLES_ALL
#define PME_MONT_L1I_PREFETCHES
#define PME_MONT_L2D_OZQ_CANCELS1_ANY
#define PME_MONT_IA64_TAGGED_INST_RETIRED_IBRP2_PMC32_33
#define PME_MONT_L1I_FILLS
#define PME_MONT_IA64_TAGGED_INST_RETIRED_IBRP0_PMC32_33
#define PME_MONT_L2I_PREFETCHES
#define PME_MONT_ISB_BUNPAIRS_IN
#define PME_MONT_L1I_STRM_PREFETCHES
#define PME_MONT_L1I_FETCH_ISB_HIT
#define PME_MONT_L1I_FETCH_RAB_HIT
#define PFMLIB_ERR_FEATCOMB
Definition: pfmlib.h:292
#define PFMLIB_MAX_PMCS
Definition: pfmlib.h:41
#define PFMLIB_ERR_IRRALIGN
Definition: pfmlib.h:304
#define PFMLIB_ERR_EVTSET
Definition: pfmlib.h:293
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
#define PFMLIB_ERR_EVTINCOMP
Definition: pfmlib.h:294
#define PFMLIB_ERR_DRRTOOMANY
Definition: pfmlib.h:302
#define PFMLIB_ERR_DRRINVAL
Definition: pfmlib.h:301
#define PFMLIB_ERR_INVAL
Definition: pfmlib.h:285
static int pfm_regmask_clr(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:332
static int pfm_regmask_andnot(pfmlib_regmask_t *dst, pfmlib_regmask_t *h1, pfmlib_regmask_t *h2)
Definition: pfmlib.h:386
#define PFMLIB_ERR_TOOMANY
Definition: pfmlib.h:295
#define PFMLIB_ERR_IRRTOOBIG
Definition: pfmlib.h:297
pfm_err_t pfm_get_impl_counters(pfmlib_regmask_t *impl_counters)
static int pfm_regmask_isset(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:313
#define PFMLIB_MONTECITO_PMU
Definition: pfmlib.h:226
#define PFMLIB_ERR_IRRTOOMANY
Definition: pfmlib.h:300
#define PFMLIB_ERR_NOASSIGN
Definition: pfmlib.h:288
#define PFMLIB_PFP_SYSTEMWIDE
Definition: pfmlib.h:121
#define PFMLIB_ERR_IRRINVAL
Definition: pfmlib.h:299
pfm_err_t pfm_get_event_code(unsigned int idx, int *code)
#define PFMLIB_ERR_IRRFLAGS
Definition: pfmlib.h:305
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
#define pme_code
#define evt_use_opcm(e)
static int cancel_events[]
static int pfm_dispatch_iear(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp)
static int pfm_dispatch_etb(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp)
static int compute_normal_rr(pfmlib_mont_input_rr_t *irr, int dfl_plm, int n, int *base_idx, pfmlib_mont_output_rr_t *orr)
static int pfm_mont_dispatch_counters(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp)
int pfm_mont_irange_is_fine(pfmlib_output_param_t *outp, pfmlib_mont_output_param_t *mod_out)
int pfm_mont_is_iear_tlb(unsigned int i)
int pfm_mont_support_opcm(unsigned int i)
int pfm_mont_is_ear(unsigned int i)
static int pfm_dispatch_ipear(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp)
int pfm_mont_is_dear_cache(unsigned int i)
pfm_pmu_support_t montecito_support
static int check_range_plm(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in)
int pfm_mont_get_event_umask(unsigned int i, unsigned long *umask)
static unsigned int pfm_mont_get_num_event_masks(unsigned int event)
static const unsigned long iod_tab[8]
static int check_cross_groups(pfmlib_input_param_t *inp, unsigned int *l1d_event, unsigned long *l2d_set1_mask, unsigned long *l2d_set2_mask)
int pfm_mont_get_event_set(unsigned int i, int *set)
#define is_iear(i)
static unsigned int l2d_set2_cnts[]
static int pfm_mont_dispatch_events(pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
int pfm_mont_is_dear_alat(unsigned int i)
#define FINE_MODE_MASK
#define has_darr(i)
static int pfm_mont_get_cycle_event(pfmlib_event_t *e)
#define DR_USED
int pfm_mont_support_darr(unsigned int i)
static int has_cpu_cycles_qual(pfmlib_input_param_t *inp)
#define NPREFETCH_DUAL_EVENTS
int pfm_mont_get_event_maxincr(unsigned int i, unsigned int *maxincr)
#define has_opcm(i)
static char * pfm_mont_get_event_name(unsigned int i)
static int pfm_dispatch_irange(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp, pfmlib_mont_output_param_t *mod_out)
#define is_ear(i)
static void pfm_mont_get_impl_pmds(pfmlib_regmask_t *impl_pmds)
static int compute_fine_rr(pfmlib_mont_input_rr_t *irr, int dfl_plm, int n, int *base_idx, pfmlib_mont_output_rr_t *orr)
#define NPREFETCH_EVENTS
static int compute_single_rr(pfmlib_mont_input_rr_t *irr, int dfl_plm, int *base_idx, pfmlib_mont_output_rr_t *orr)
static unsigned int check_inst_retired_events(pfmlib_input_param_t *inp, unsigned long *retired_mask)
static char * pfm_mont_get_event_mask_name(unsigned int event, unsigned int mask)
static int check_fine_mode_possible(pfmlib_mont_input_rr_t *rr, int n)
int pfm_mont_get_ear_mode(unsigned int i, pfmlib_mont_ear_mode_t *m)
static int pfm_mont_get_event_code(unsigned int i, unsigned int cnt, int *code)
static void pfm_mont_get_impl_counters(pfmlib_regmask_t *impl_counters)
static int pfm_mont_get_event_mask_code(unsigned int event, unsigned int mask, unsigned int *code)
static int prefetch_dual_events[]
#define evt_set(e)
static int pfm_dispatch_opcm(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp, pfmlib_mont_output_param_t *mod_out)
int pfm_mont_is_iear_cache(unsigned int i)
#define is_etb(i)
#define has_iarr(i)
#define is_ear_alat(i)
#define NCANCEL_EVENTS
#define is_ear_cache(i)
#define OP_USED
static int pfm_mont_get_event_description(unsigned int ev, char **str)
static int pfm_mont_detect(void)
static int prefetch_events[]
#define IR_USED
#define has_all(i)
static int pfm_mont_get_inst_retired(pfmlib_event_t *e)
int pfm_mont_support_all(unsigned int i)
#define evt_grp(e)
int pfm_mont_get_event_group(unsigned int i, int *grp)
#define is_ear_tlb(i)
#define has_mesi(i)
#define evt_caf(e)
#define PMC36_DFL_VAL
static int pfm_mont_get_event_mask_desc(unsigned int event, unsigned int mask, char **desc)
int pfm_mont_support_iarr(unsigned int i)
static void print_one_range(pfmlib_mont_input_rr_desc_t *in_rr, pfmlib_mont_output_rr_desc_t *out_rr, pfmlib_reg_t *dbr, int base_idx, int n_pairs, int fine_mode, unsigned int rr_flags)
#define UNEXISTING_SET
int pfm_mont_is_etb(unsigned int i)
static void do_normal_rr(unsigned long start, unsigned long end, pfmlib_reg_t *br, int nbr, int dir, int *idx, int *reg_idx, int plm)
static int pfm_dispatch_drange(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp, pfmlib_mont_output_param_t *mod_out)
#define evt_use_irange(e)
static void pfm_mont_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
static unsigned int l2d_set1_cnts[]
int pfm_mont_is_dear(unsigned int i)
int pfm_mont_is_iear(unsigned int i)
#define evt_use_drange(e)
static int check_cancel_events(pfmlib_input_param_t *inp)
int pfm_mont_get_event_type(unsigned int i, int *type)
static int pfm_dispatch_dear(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in, pfmlib_output_param_t *outp)
static void pfm_mont_get_hw_counter_width(unsigned int *width)
#define evt_umask(e)
static void pfm_mont_get_impl_pmcs(pfmlib_regmask_t *impl_pmcs)
int pfm_mont_is_dear_tlb(unsigned int i)
static int check_qualifier_constraints(pfmlib_input_param_t *inp, pfmlib_mont_input_param_t *mod_in)
static int check_intervals(pfmlib_mont_input_rr_t *irr, int mode, unsigned int *n_intervals)
static int check_prefetch_events(pfmlib_input_param_t *inp, pfmlib_mont_input_rr_t *irr, unsigned int *count, int *base_idx, int *dup)
#define is_dear(i)
#define PFMLIB_MONT_FL_EVT_ALL_THRD
#define PMU_MONT_COUNTER_WIDTH
#define PMU_MONT_FIRST_COUNTER
#define PFMLIB_MONT_FL_EVT_NO_QUALCHECK
#define PFMLIB_MONT_EVT_L1D_CACHE_GRP
#define PMU_MONT_NUM_COUNTERS
#define PMU_MONT_NUM_PMCS
#define PFMLIB_MONT_IRR_DEMAND_FETCH
#define PFMLIB_MONT_IRR_PREFETCH_MATCH
#define PFMLIB_MONT_RR_NO_FINE_MODE
pfmlib_mont_ear_mode_t
@ PFMLIB_MONT_EAR_TLB_MODE
@ PFMLIB_MONT_EAR_CACHE_MODE
@ PFMLIB_MONT_EAR_ALAT_MODE
#define PMU_MONT_NUM_PMDS
#define PFMLIB_MONT_RR_INV
#define PFMLIB_MONT_EVT_NO_SET
#define PFMLIB_MONT_EVT_L2D_CACHE_GRP
void __pfm_vbprintf(const char *fmt,...)
Definition: pfmlib_priv.c:52
#define PFMLIB_VERBOSE()
Definition: pfmlib_priv.h:77
#define DPRINT(fmt, a...)
Definition: pfmlib_priv.h:90
#define ALIGN_DOWN(a, p)
Definition: pfmlib_priv.h:99
#define PFMLIB_DEBUG()
Definition: pfmlib_priv.h:76
#define PFMLIB_CNT_FIRST
Definition: pfmlib_priv.h:62
static int pfm_ia64_fls(unsigned long x)
static int pfm_ia64_get_cpu_family(void)
int
Definition: sde_internal.h:89
long long int long long
Definition: sde_internal.h:85
unsigned long db_mask
unsigned long db_plm
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
unsigned int pfp_flags
Definition: pfmlib.h:111
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:113
unsigned int pfp_event_count
Definition: pfmlib.h:109
unsigned char ear_used
unsigned long ear_umask
unsigned int ear_plm
pfmlib_mont_ear_mode_t ear_mode
unsigned char etb_brt
unsigned char etb_used
unsigned char etb_ptm
unsigned int etb_plm
unsigned char etb_ppm
unsigned char etb_tm
pfmlib_mont_ear_t pfp_mont_iear
pfmlib_mont_input_rr_t pfp_mont_irange
pfmlib_mont_counter_t pfp_mont_counters[PMU_MONT_NUM_COUNTERS]
pfmlib_mont_input_rr_t pfp_mont_drange
pfmlib_mont_ipear_t pfp_mont_ipear
pfmlib_mont_opcm_t pfp_mont_opcm2
pfmlib_mont_opcm_t pfp_mont_opcm1
pfmlib_mont_ear_t pfp_mont_dear
pfmlib_mont_etb_t pfp_mont_etb
pfmlib_mont_input_rr_desc_t rr_limits[4]
unsigned char ipear_used
unsigned short ipear_delay
unsigned long opcm_match
unsigned char opcm_i
unsigned char opcm_b
unsigned long opcm_mask
unsigned char opcm_f
unsigned char opcm_used
unsigned char opcm_m
pfmlib_mont_output_rr_t pfp_mont_irange
pfmlib_mont_output_rr_t pfp_mont_drange
pfmlib_mont_output_rr_desc_t rr_infos[4]
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 reg_alt_addr
Definition: pfmlib.h:102
unsigned long long reg_addr
Definition: pfmlib.h:99
pfmlib_regmask_bits_t bits[PFMLIB_REG_BV]
Definition: pfmlib.h:76
unsigned long pme_counters
unsigned int pme_maxincr
char * pme_name
char * pme_desc
unsigned long val
br_mask_reg_t db
unsigned long etbc_plm
unsigned long iarc_ig_ibrp1
unsigned long ipear_pm
unsigned long darc_ena_dbrp0
unsigned long etbc_ptm
unsigned long opcm_inv
struct pfm_mont_pmc_reg_t::@66 pmc37_mont_cache_reg
unsigned long iarc_ig_ibrp0
unsigned long dear_pm
unsigned long dear_ism
struct pfm_mont_pmc_reg_t::@65 pmc36_mont_reg
unsigned long opcm_ch3_ig_opcm
unsigned long pmc_ism
unsigned long dear_plm
unsigned long ipear_mode
struct pfm_mont_pmc_reg_t::@71 pmc41_mont_reg
unsigned long iarc_fine
unsigned long pmc_thres
unsigned long etbc_ds
unsigned long ipear_delay
unsigned long dear_mode
struct pfm_mont_pmc_reg_t::@64 pmc33_35_mont_reg
unsigned long pmc_s
unsigned long ipear_plm
unsigned long opcm_ch1_ig_opcm
unsigned long darc_cfg_dtag1
unsigned long pmc_i
unsigned long darc_ena_dbrp2
struct pfm_mont_pmc_reg_t::@70 pmc39_mont_reg
unsigned long pmc_umask
unsigned long pmc_pm
unsigned long opcm_i
unsigned long iarc_ig_ibrp3
unsigned long etbc_ppm
unsigned long pmc_oi
unsigned long darc_ena_dbrp3
unsigned long pmc_e
unsigned long iear_pm
unsigned long opcm_mask
struct pfm_mont_pmc_reg_t::@67 pmc37_mont_tlb_reg
unsigned long darc_ena_dbrp1
struct pfm_mont_pmc_reg_t::@69 pmc42_mont_reg
unsigned long opcm_ch2_ig_opcm
unsigned long opcm_m
unsigned long etbc_brt
unsigned long pmc_plm
unsigned long opcm_b
struct pfm_mont_pmc_reg_t::@63 pmc32_34_mont_reg
unsigned long darc_cfg_dtag3
unsigned long iear_ct
struct pfm_mont_pmc_reg_t::@68 pmc40_mont_reg
unsigned long pmc_all
unsigned long etbc_pm
unsigned long opcm_ig_ad
unsigned long iear_plm
unsigned long etbc_tm
unsigned long dear_umask
unsigned long pmc_es
unsigned long iarc_ig_ibrp2
unsigned long opcm_ch0_ig_opcm
unsigned long darc_cfg_dtag0
unsigned long darc_cfg_dtag2
unsigned long opcm_match
unsigned long iear_umask
unsigned long pmc_val
struct pfm_mont_pmc_reg_t::@72 pmc38_mont_reg
unsigned long pmc_m
unsigned long opcm_f