|
Packit |
577717 |
/* $Id: x86.c,v 1.5 2005/03/14 01:48:42 mikpe Exp $
|
|
Packit |
577717 |
* x86-specific code.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Copyright (C) 1999-2004 Mikael Pettersson
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include "libperfctr.h"
|
|
Packit |
577717 |
#include "arch.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void do_setup(const struct perfctr_info *info,
|
|
Packit |
577717 |
struct perfctr_cpu_control *cpu_control)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int tsc_on = 1;
|
|
Packit |
577717 |
unsigned int nractrs = 1;
|
|
Packit |
577717 |
unsigned int pmc_map0 = 0;
|
|
Packit |
577717 |
unsigned int evntsel0 = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
memset(cpu_control, 0, sizeof *cpu_control);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Attempt to set up control to count clocks via the TSC
|
|
Packit |
577717 |
and retired instructions via PMC0. */
|
|
Packit |
577717 |
switch( info->cpu_type ) {
|
|
Packit |
577717 |
case PERFCTR_X86_GENERIC:
|
|
Packit |
577717 |
nractrs = 0; /* no PMCs available */
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
#if !defined(__x86_64__)
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P5:
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P5MMX:
|
|
Packit |
577717 |
case PERFCTR_X86_CYRIX_MII:
|
|
Packit |
577717 |
/* event 0x16 (INSTRUCTIONS_EXECUTED), count at CPL 3 */
|
|
Packit |
577717 |
evntsel0 = 0x16 | (2 << 6);
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P6:
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_PII:
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_PIII:
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_PENTM:
|
|
Packit |
577717 |
case PERFCTR_X86_AMD_K7:
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
case PERFCTR_X86_AMD_K8:
|
|
Packit |
577717 |
case PERFCTR_X86_AMD_K8C:
|
|
Packit |
577717 |
/* event 0xC0 (INST_RETIRED), count at CPL > 0, Enable */
|
|
Packit |
577717 |
evntsel0 = 0xC0 | (1 << 16) | (1 << 22);
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
#if !defined(__x86_64__)
|
|
Packit |
577717 |
case PERFCTR_X86_WINCHIP_C6:
|
|
Packit |
577717 |
tsc_on = 0; /* no working TSC available */
|
|
Packit |
577717 |
evntsel0 = 0x02; /* X86_INSTRUCTIONS */
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PERFCTR_X86_WINCHIP_2:
|
|
Packit |
577717 |
tsc_on = 0; /* no working TSC available */
|
|
Packit |
577717 |
evntsel0 = 0x16; /* INSTRUCTIONS_EXECUTED */
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PERFCTR_X86_VIA_C3:
|
|
Packit |
577717 |
pmc_map0 = 1; /* redirect PMC0 to PERFCTR1 */
|
|
Packit |
577717 |
evntsel0 = 0xC0; /* INSTRUCTIONS_EXECUTED */
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P4:
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P4M2:
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
case PERFCTR_X86_INTEL_P4M3:
|
|
Packit |
577717 |
/* PMC0: IQ_COUNTER0 with fast RDPMC */
|
|
Packit |
577717 |
pmc_map0 = 0x0C | (1 << 31);
|
|
Packit |
577717 |
/* IQ_CCCR0: required flags, ESCR 4 (CRU_ESCR0), Enable */
|
|
Packit |
577717 |
evntsel0 = (0x3 << 16) | (4 << 13) | (1 << 12);
|
|
Packit |
577717 |
/* CRU_ESCR0: event 2 (instr_retired), NBOGUSNTAG, CPL>0 */
|
|
Packit |
577717 |
cpu_control->p4.escr[0] = (2 << 25) | (1 << 9) | (1 << 2);
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
fprintf(stderr, "cpu type %u (%s) not supported\n",
|
|
Packit |
577717 |
info->cpu_type, perfctr_info_cpu_name(info));
|
|
Packit |
577717 |
exit(1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
cpu_control->tsc_on = tsc_on;
|
|
Packit |
577717 |
cpu_control->nractrs = nractrs;
|
|
Packit |
577717 |
cpu_control->pmc_map[0] = pmc_map0;
|
|
Packit |
577717 |
cpu_control->evntsel[0] = evntsel0;
|
|
Packit |
577717 |
}
|