Ejemplo n.º 1
0
static void
show_event_info(char *name, unsigned int idx)
{
	pfmlib_regmask_t cnt, impl_cnt;
	char *desc;
	unsigned int n1, n2, i, c;
	int code, prev_code = 0, first = 1;
	int ret;

	pfm_get_event_counters(idx, &cnt);
	pfm_get_num_counters(&n2);
	pfm_get_impl_counters(&impl_cnt);

	n1 = n2;
	printf("#-----------------------------\n"
	       "Name     : %s\n",
	       name);

	pfm_get_event_description(idx, &desc);
 	printf("Desc     : %s\n", desc);
	free(desc);

	printf("Code     :");
	for (i=0; n1; i++) {
		if (pfm_regmask_isset(&impl_cnt, i))
			n1--;
		if (pfm_regmask_isset(&cnt, i)) {
		    pfm_get_event_code_counter(idx,i,&code);
		    if (first == 1 || code != prev_code) {
			    printf(" 0x%x", code);
		    	    first = 0;
		    }
		    prev_code = code;
		}
	}
	putchar('\n');

	n1 = n2;
	printf("Counters : [ ");
	for (i=0; n1; i++) {
		if (pfm_regmask_isset(&impl_cnt, i))
			n1--;
		if (pfm_regmask_isset(&cnt, i))
			printf("%d ", i);
	}
	puts("]");
	pfm_get_num_event_masks(idx, &n1);
	for (i = 0; i < n1; i++) {
		ret = pfm_get_event_mask_name(idx, i, name, max_len+1);
		if (ret != PFMLIB_SUCCESS)
			continue;
		pfm_get_event_mask_description(idx, i, &desc);
		pfm_get_event_mask_code(idx, i, &c);
		printf("Umask-%02u : 0x%02x : [%s] : %s\n", i, c, name, desc);
		free(desc);
	}
}
static int setup_preset_term(int *native, pfmlib_event_t *event)
{
    /* It seems this could be greatly simplified. If impl_cnt is non-zero,
	the event lives on a counter. Therefore the entire routine could be:
	if (impl_cnt!= 0) encode_native_event.
	Am I wrong?
    */
  pfmlib_regmask_t impl_cnt, evnt_cnt;
  unsigned int n;
  int j, ret;

  /* find out which counters it lives on */
  if ((ret = pfm_get_event_counters(event->event,&evnt_cnt)) != PFMLIB_SUCCESS)
    {
      PAPIERROR("pfm_get_event_counters(%d,%p): %s",event->event,&evnt_cnt,pfm_strerror(ret));
      return(PAPI_EBUG);
    }
  if ((ret = pfm_get_impl_counters(&impl_cnt)) != PFMLIB_SUCCESS)
    {
      PAPIERROR("pfm_get_impl_counters(%p): %s", &impl_cnt, pfm_strerror(ret));
      return(PAPI_EBUG);
    }

  /* Make sure this event lives on some counter, if so, put in the description. If not, BUG */
  if ((ret = pfm_get_num_counters(&n)) != PFMLIB_SUCCESS)
    {
      PAPIERROR("pfm_get_num_counters(%d): %s", n, pfm_strerror(ret));
      return(PAPI_EBUG);
    }

  for (j=0;n;j++)
    {
      if (pfm_regmask_isset(&impl_cnt, j))
	{
	  n--;
	  if (pfm_regmask_isset(&evnt_cnt,j))
	    {
	      *native = encode_native_event(event->event,event->num_masks,event->unit_masks);
	      return(PAPI_OK);
	    }
	}
    }

  PAPIERROR("PAPI preset 0x%08x PFM event %d did not have any available counters", event->event, j);
  return(PAPI_ENOEVNT);
}
Ejemplo n.º 3
0
static void
pfm_gen_ia64_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
{
	unsigned int i;

	memset(counters, 0, sizeof(*counters));

	for(i=0; i < pfm_gen_ia64_counters; i++) {
		if (pfm_regmask_isset(&generic_pe[j].pme_counters, i))
			pfm_regmask_set(counters, i);
	}
}
Ejemplo n.º 4
0
static int
valid_assign(unsigned int *as, pfmlib_regmask_t *r_pmcs, unsigned int cnt)
{
	unsigned int i;
	for(i=0; i < cnt; i++) {
		if (as[i]==0) return 0;
		/*
		 * take care of restricted PMC registers
		 */
		if (pfm_regmask_isset(r_pmcs, as[i]))
			return 0;
	}
	return 1;
}
Ejemplo n.º 5
0
int
main(int argc, char **argv)
{
	unsigned int i, cnum = 0;
	pfarg_reg_t pc[NUM_PMCS];
	pfmlib_regmask_t impl_pmcs;
	unsigned int num_pmcs;

	/*
	 * Initialize pfm library (required before we can use it)
	 */
	if (pfm_initialize() != PFMLIB_SUCCESS) {
		printf("Can't initialize library\n");
		exit(1);
	}

	memset(&impl_pmcs, 0, sizeof(impl_pmcs));
	memset(pc, 0, sizeof(pc));
	
	pfm_get_impl_pmcs(&impl_pmcs);
	pfm_get_num_pmcs(&num_pmcs);

	for(i=0; num_pmcs ; i++) {
		if (pfm_regmask_isset(&impl_pmcs, i) == 0) continue;
		pc[cnum++].reg_num = i;
		num_pmcs--;
	}

	if (perfmonctl(0, PFM_GET_PMC_RESET_VAL, pc, cnum) == -1 ) {
		if (errno == ENOSYS) {
			fatal_error("Your kernel does not have performance monitoring support!\n");
		}
		fatal_error("cannot get reset values: %s\n", strerror(errno));
	}

	for (i=0; i < cnum; i++) {
		printf("PMC%u 0x%lx\n", pc[i].reg_num, pc[i].reg_value);

	}
	return 0;
}
Ejemplo n.º 6
0
/**
 * pentium4_dispatch_events
 *
 * Examine each desired event specified in "input" and find an appropriate
 * ESCR/CCCR pair that can be used to count them.
 **/
static int pentium4_dispatch_events(pfmlib_input_param_t *input,
				    void *model_input,
				    pfmlib_output_param_t *output,
				    void *model_output)
{
	unsigned int assigned_pmcs[PENTIUM4_NUM_PMCS] = {0};
	unsigned int event, event_mask, mask;
	unsigned int bit, tag_value, tag_enable;
	unsigned int plm;
	unsigned int i, j, k, m, n;
	int escr, escr_pmc;
	int cccr, cccr_pmc, cccr_pmd;
	int assigned;
	pentium4_escr_value_t escr_value;
	pentium4_cccr_value_t cccr_value;

	if (input->pfp_event_count > PENTIUM4_NUM_PMDS) {
		/* Can't specify more events than we have counters. */
		return PFMLIB_ERR_TOOMANY;
	}

	if (input->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
		/* Can't specify privilege levels 1 or 2. */
		return PFMLIB_ERR_INVAL;
	}

	/* Examine each event specified in input->pfp_events. i counts
	 * through the input->pfp_events array, and j counts through the
	 * PMCs in output->pfp_pmcs as they are set up.
	 */
	for (i = 0, j = 0; i < input->pfp_event_count; i++) {

		if (input->pfp_events[i].plm & (PFM_PLM1|PFM_PLM2)) {
			/* Can't specify privilege levels 1 or 2. */
			return PFMLIB_ERR_INVAL;
		}

		/*
		 * INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott)
		 */
		if (input->pfp_events[i].event == PME_INSTR_COMPLETED &&
		    p4_model != 3 && p4_model != 4 && p4_model != 6)
				return PFMLIB_ERR_EVTINCOMP;

		event = input->pfp_events[i].event;
		assigned = 0;

		/* Use the event-specific privilege mask if set.
		 * Otherwise use the default privilege mask.
		 */
		plm = input->pfp_events[i].plm ?
		      input->pfp_events[i].plm : input->pfp_dfl_plm;

		/* Examine each ESCR that this event could be assigned to. */
		for (k = 0; k < MAX_ESCRS_PER_EVENT && !assigned; k++) {
			escr = pentium4_events[event].allowed_escrs[k];
			if (escr < 0)
				continue;

			/* Make sure this ESCR isn't already assigned
			 * and isn't on the "unavailable" list.
			 */
			escr_pmc = pentium4_escrs[escr].pmc;
			if (assigned_pmcs[escr_pmc] ||
			    pfm_regmask_isset(&input->pfp_unavail_pmcs, escr_pmc)) {
				continue;
			}

			/* Examine each CCCR that can be used with this ESCR. */
			for (m = 0; m < MAX_CCCRS_PER_ESCR && !assigned; m++) {
				cccr = pentium4_escrs[escr].allowed_cccrs[m];
				if (cccr < 0) {
					continue;
				}

				/* Make sure this CCCR isn't already assigned
				 * and isn't on the "unavailable" list.
				 */
				cccr_pmc = pentium4_cccrs[cccr].pmc;
				cccr_pmd = pentium4_cccrs[cccr].pmd;
				if (assigned_pmcs[cccr_pmc] ||
				    pfm_regmask_isset(&input->pfp_unavail_pmcs, cccr_pmc)) {
					continue;
				}

				/* Found an available ESCR/CCCR pair. */
				assigned = 1;
				assigned_pmcs[escr_pmc] = 1;
				assigned_pmcs[cccr_pmc] = 1;

				/* Calculate the event-mask value. Invalid masks
				 * specified by the caller are ignored.
				 */
				event_mask = 0;
				tag_value = 0;
				tag_enable = 0;
				for (n = 0; n < input->pfp_events[i].num_masks; n++) {
					mask = input->pfp_events[i].unit_masks[n];
					bit = pentium4_events[event].event_masks[mask].bit;
					if (bit < EVENT_MASK_BITS &&
						pentium4_events[event].event_masks[mask].name) {
						event_mask |= (1 << bit);
					}
					if (bit >= EVENT_MASK_BITS &&
						pentium4_events[event].event_masks[mask].name) {
						tag_value |= (1 << (bit - EVENT_MASK_BITS));
						tag_enable = 1;
					}
				}

				/* Set up the ESCR and CCCR register values. */
				escr_value.val = 0;

				escr_value.bits.t1_usr       = 0; /* controlled by kernel */
				escr_value.bits.t1_os        = 0; /* controlled by kernel */
				escr_value.bits.t0_usr       = (plm & PFM_PLM3) ? 1 : 0;
				escr_value.bits.t0_os        = (plm & PFM_PLM0) ? 1 : 0;
				escr_value.bits.tag_enable   = tag_enable;
				escr_value.bits.tag_value    = tag_value;
				escr_value.bits.event_mask   = event_mask;
				escr_value.bits.event_select = pentium4_events[event].event_select;
				escr_value.bits.reserved     = 0;

				cccr_value.val = 0;

				cccr_value.bits.reserved1     = 0;
				cccr_value.bits.enable        = 1;
				cccr_value.bits.escr_select   = pentium4_events[event].escr_select;
				cccr_value.bits.active_thread = 3; /* FIXME: This is set to count when either logical
								    *        CPU is active. Need a way to distinguish
								    *        between logical CPUs when HT is enabled. */
				cccr_value.bits.compare       = 0; /* FIXME: What do we do with "threshold" settings? */
				cccr_value.bits.complement    = 0; /* FIXME: What do we do with "threshold" settings? */
				cccr_value.bits.threshold     = 0; /* FIXME: What do we do with "threshold" settings? */
				cccr_value.bits.force_ovf     = 0; /* FIXME: Do we want to allow "forcing" overflow
								    *        interrupts on all counter increments? */
				cccr_value.bits.ovf_pmi_t0    = 1;
				cccr_value.bits.ovf_pmi_t1    = 0; /* PMI taken care of by kernel typically */
				cccr_value.bits.reserved2     = 0;
				cccr_value.bits.cascade       = 0; /* FIXME: How do we handle "cascading" counters? */
				cccr_value.bits.overflow      = 0;

				/* Special processing for the replay event:
					Remove virtual mask bits from actual mask;
					scan mask bit list and OR bit values for each virtual mask
					into the PEBS ENABLE and PEBS MATRIX VERT registers */
				if (event == PME_REPLAY_EVENT) {
					escr_value.bits.event_mask &= P4_REPLAY_REAL_MASK;	 /* remove virtual mask bits */
					if (event_mask & P4_REPLAY_VIRT_MASK) {				 /* find a valid virtual mask */
						output->pfp_pmcs[j].reg_value = 0;
						output->pfp_pmcs[j].reg_num = PMC_PEBS_ENABLE;
						output->pfp_pmcs[j].reg_addr = p4_pmc_regmap[PMC_PEBS_ENABLE].addr;
						output->pfp_pmcs[j+1].reg_value = 0;
						output->pfp_pmcs[j+1].reg_num = PMC_PEBS_MATRIX_VERT;
						output->pfp_pmcs[j+1].reg_addr = p4_pmc_regmap[PMC_PEBS_MATRIX_VERT].addr;
						for (n = 0; n < input->pfp_events[i].num_masks; n++) {
							mask = input->pfp_events[i].unit_masks[n];
							if (mask > 1 && mask < 11) { /* process each valid mask we find */
								output->pfp_pmcs[j].reg_value |= p4_replay_regs[mask].enb;
								output->pfp_pmcs[j+1].reg_value |= p4_replay_regs[mask].mat_vert;
							}
						}
						j += 2;
						output->pfp_pmc_count += 2;
					}
				}

				 /* Set up the PMCs in the
				 * output->pfp_pmcs array.
				 */
				output->pfp_pmcs[j].reg_num = escr_pmc;
				output->pfp_pmcs[j].reg_value = escr_value.val;
				output->pfp_pmcs[j].reg_addr = p4_pmc_regmap[escr_pmc].addr;
				j++;

				__pfm_vbprintf("[%s(pmc%u)=0x%lx os=%u usr=%u tag=%u tagval=0x%x mask=%u sel=0x%x] %s\n",
						p4_pmc_regmap[escr_pmc].name,
						escr_pmc,
						escr_value.val,
						escr_value.bits.t0_os,
						escr_value.bits.t0_usr,
						escr_value.bits.tag_enable,
						escr_value.bits.tag_value,
						escr_value.bits.event_mask,
						escr_value.bits.event_select,
						pentium4_events[event].name);

				output->pfp_pmcs[j].reg_num = cccr_pmc;
				output->pfp_pmcs[j].reg_value = cccr_value.val;
				output->pfp_pmcs[j].reg_addr = p4_pmc_regmap[cccr_pmc].addr;

				output->pfp_pmds[i].reg_num = cccr_pmd;
				output->pfp_pmds[i].reg_addr = p4_pmd_regmap[cccr_pmd].addr;

				__pfm_vbprintf("[%s(pmc%u)=0x%lx ena=1 sel=0x%x cmp=%u cmpl=%u thres=%u edg=%u cas=%u] %s\n",
						p4_pmc_regmap[cccr_pmc].name,
						cccr_pmc,
						cccr_value.val,
						cccr_value.bits.escr_select,
						cccr_value.bits.compare,
						cccr_value.bits.complement,
						cccr_value.bits.threshold,
						cccr_value.bits.edge,
						cccr_value.bits.cascade,
						pentium4_events[event].name);
				__pfm_vbprintf("[%s(pmd%u)]\n", p4_pmd_regmap[output->pfp_pmds[i].reg_num].name, output->pfp_pmds[i].reg_num);
				j++;

				output->pfp_pmc_count += 2;
			}
		}
		if (k == MAX_ESCRS_PER_EVENT && !assigned) {
			/* Couldn't find an available ESCR and/or CCCR. */
			return PFMLIB_ERR_NOASSIGN;
		}
	}
	output->pfp_pmd_count = input->pfp_event_count;

	return PFMLIB_SUCCESS;
}