Blame src/perfctr-2.6.x/examples/global/x86.c

Packit Service a1973e
/* $Id: x86.c,v 1.2.2.11 2010/11/07 19:46:06 mikpe Exp $
Packit Service a1973e
 * x86-specific code.
Packit Service a1973e
 *
Packit Service a1973e
 * Copyright (C) 2000-2010  Mikael Pettersson
Packit Service a1973e
 */
Packit Service a1973e
#include <stdio.h>
Packit Service a1973e
#include <stdlib.h>
Packit Service a1973e
#include <string.h>
Packit Service a1973e
#include "libperfctr.h"
Packit Service a1973e
#include "arch.h"
Packit Service a1973e
Packit Service a1973e
void setup_control(const struct perfctr_info *info,
Packit Service a1973e
		   struct perfctr_cpu_control *control)
Packit Service a1973e
{
Packit Service a1973e
    unsigned int tsc_on = 1;
Packit Service a1973e
    unsigned int nractrs = 1;
Packit Service a1973e
    unsigned int pmc_map0 = 0;
Packit Service a1973e
    unsigned int evntsel0 = 0;
Packit Service a1973e
Packit Service a1973e
    memset(control, 0, sizeof *control);
Packit Service a1973e
Packit Service a1973e
    /* Attempt to set up control to count clocks via the TSC
Packit Service a1973e
       and FLOPS via PMC0. */
Packit Service a1973e
    switch (info->cpu_type) {
Packit Service a1973e
      case PERFCTR_X86_GENERIC:
Packit Service a1973e
	nractrs = 0;		/* no PMCs available */
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_AMD_K8:
Packit Service a1973e
      case PERFCTR_X86_AMD_K8C:
Packit Service a1973e
      case PERFCTR_X86_AMD_FAM10H:
Packit Service a1973e
	/* RETIRED_FPU_INSTRS, Unit Mask "x87 instrs", any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0xCB | (0x01 << 8) | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
#if !defined(__x86_64__)
Packit Service a1973e
      case PERFCTR_X86_INTEL_P5:
Packit Service a1973e
      case PERFCTR_X86_INTEL_P5MMX:
Packit Service a1973e
      case PERFCTR_X86_CYRIX_MII:
Packit Service a1973e
	/* event 0x22 (FLOPS), any CPL */
Packit Service a1973e
	evntsel0 = 0x22 | (3 << 6);
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_INTEL_P6:
Packit Service a1973e
      case PERFCTR_X86_INTEL_PII:
Packit Service a1973e
      case PERFCTR_X86_INTEL_PIII:
Packit Service a1973e
      case PERFCTR_X86_INTEL_PENTM:
Packit Service a1973e
      case PERFCTR_X86_INTEL_CORE:
Packit Service a1973e
	/* note: FLOPS is only available in PERFCTR0 */
Packit Service a1973e
	/* event 0xC1 (FLOPS), any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0xC1 | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
#endif
Packit Service a1973e
      case PERFCTR_X86_INTEL_CORE2:
Packit Service a1973e
	/* event 0xC1 umask 0xFE (X87_OPS_RETIRED_ANY), any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0xC1 | (0xFE << 8) | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_INTEL_ATOM:
Packit Service a1973e
	/* Atom's architectural events don't include FLOPS */
Packit Service a1973e
	counting_mips = 1;
Packit Service a1973e
	/* event 0xC0 (RETIRED_INSTRUCTIONS), any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0xC0 | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_INTEL_NHLM:
Packit Service a1973e
      case PERFCTR_X86_INTEL_WSTMR:
Packit Service a1973e
	/* FP_COMP_OPS_EXE.ANY, any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0x10 | (0xFF << 8) | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
#if !defined(__x86_64__)
Packit Service a1973e
      case PERFCTR_X86_AMD_K7:
Packit Service a1973e
	/* K7 apparently can't count FLOPS. */
Packit Service a1973e
	counting_mips = 1;
Packit Service a1973e
	/* event 0xC0 (RETIRED_INSTRUCTIONS), any CPL, Enable */
Packit Service a1973e
	evntsel0 = 0xC0 | (3 << 16) | (1 << 22);
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_WINCHIP_C6:
Packit Service a1973e
	counting_mips = 1;	/* can't count FLOPS */
Packit Service a1973e
	tsc_on = 0;		/* no working TSC available */
Packit Service a1973e
	evntsel0 = 0x02;	/* X86_INSTRUCTIONS */
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_WINCHIP_2:
Packit Service a1973e
	counting_mips = 1;	/* can't count FLOPS */
Packit Service a1973e
	tsc_on = 0;		/* no working TSC available */
Packit Service a1973e
	evntsel0 = 0x16;	/* INSTRUCTIONS_EXECUTED */
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_VIA_C3:
Packit Service a1973e
	counting_mips = 1;	/* can't count FLOPS */
Packit Service a1973e
	pmc_map0 = 1;		/* redirect PMC0 to PERFCTR1 */
Packit Service a1973e
	evntsel0 = 0xC0;	/* INSTRUCTIONS_EXECUTED */
Packit Service a1973e
	break;
Packit Service a1973e
      case PERFCTR_X86_INTEL_P4:
Packit Service a1973e
      case PERFCTR_X86_INTEL_P4M2:
Packit Service a1973e
#endif
Packit Service a1973e
      case PERFCTR_X86_INTEL_P4M3:
Packit Service a1973e
	nractrs = 2;
Packit Service a1973e
	/* set up PMC(1) to produce tagged x87_FP_uop:s */
Packit Service a1973e
	control->pmc_map[1] = 0x8 | (1 << 31);
Packit Service a1973e
	control->evntsel[1] = (0x3 << 16) | (1 << 13) | (1 << 12);
Packit Service a1973e
	control->p4.escr[1] = (4 << 25) | (1 << 24) | (1 << 5) | (1 << 4) | (1 << 2);
Packit Service a1973e
	/* set up PMC(0) to count execution_event(X87_FP_retired) */
Packit Service a1973e
	pmc_map0 = 0xC | (1 << 31);
Packit Service a1973e
	evntsel0 = (0x3 << 16) | (5 << 13) | (1 << 12);
Packit Service a1973e
	control->p4.escr[0] = (0xC << 25) | (1 << 9) | (1 << 2);
Packit Service a1973e
	break;
Packit Service a1973e
      default:
Packit Service a1973e
	fprintf(stderr, "cpu_type %u (%s) not supported\n",
Packit Service a1973e
		info->cpu_type, perfctr_info_cpu_name(info));
Packit Service a1973e
	exit(1);
Packit Service a1973e
    }
Packit Service a1973e
    control->tsc_on = tsc_on;
Packit Service a1973e
    control->nractrs = nractrs;
Packit Service a1973e
    control->pmc_map[0] = pmc_map0;
Packit Service a1973e
    control->evntsel[0] = evntsel0;
Packit Service a1973e
}