Blame src/perfctr-2.6.x/usr.lib/x86.c

Packit 577717
/* $Id: x86.c,v 1.2.2.11 2010/11/07 19:46:06 mikpe Exp $
Packit 577717
 * x86-specific perfctr library procedures.
Packit 577717
 *
Packit 577717
 * Copyright (C) 1999-2010  Mikael Pettersson
Packit 577717
 */
Packit 577717
#include <stdio.h>
Packit 577717
#include "libperfctr.h"
Packit 577717
Packit 577717
struct cpuid {	/* The field order must not be changed. */
Packit 577717
    unsigned int eax;
Packit 577717
    unsigned int ebx;	/* When eax was 1, &ebx should be the start */
Packit 577717
    unsigned int edx;	/* of the 12-byte vendor identification string. */
Packit 577717
    unsigned int ecx;
Packit 577717
};
Packit 577717
Packit 577717
static void get_cpuid(unsigned int op, struct cpuid *cpuid)
Packit 577717
{
Packit 577717
    unsigned int save_ebx;
Packit 577717
    unsigned int tmp_ebx;
Packit 577717
Packit 577717
    __asm__(
Packit 577717
	"movl %%ebx, %0\n\t"
Packit 577717
	"cpuid\n\t"
Packit 577717
	"movl %%ebx, %1\n\t"
Packit 577717
	"movl %0, %%ebx"
Packit 577717
	: "=m"(save_ebx), "=m"(tmp_ebx), "=a"(cpuid->eax), "=d"(cpuid->edx), "=c"(cpuid->ecx)
Packit 577717
	: "a"(op));
Packit 577717
    cpuid->ebx = tmp_ebx;
Packit 577717
}
Packit 577717
Packit 577717
static unsigned int atom_nrctrs(void)
Packit 577717
{
Packit 577717
    struct cpuid cpuid;
Packit 577717
Packit 577717
    get_cpuid(0, &cpuid);
Packit 577717
    if (cpuid.eax < 0xA) {
Packit 577717
	printf("%s: cpuid[0].eax == %u, unable to query 0xA leaf\n",
Packit 577717
	       __FUNCTION__, cpuid.eax);
Packit 577717
	return 0;
Packit 577717
    }
Packit 577717
    get_cpuid(0xA, &cpuid);
Packit 577717
    if ((cpuid.eax & 0xff) < 2) {
Packit 577717
	printf("%s: cpuid[0xA].eax == 0x%08x appears bogus\n",
Packit 577717
	       __FUNCTION__, cpuid.eax);
Packit 577717
	return 0;
Packit 577717
    }
Packit 577717
    return ((cpuid.eax >> 8) & 0xff) + (cpuid.edx & 0x1f);
Packit 577717
}
Packit 577717
Packit 577717
unsigned int perfctr_info_nrctrs(const struct perfctr_info *info)
Packit 577717
{
Packit 577717
    switch (info->cpu_type) {
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_INTEL_P6:
Packit 577717
      case PERFCTR_X86_INTEL_PII:
Packit 577717
      case PERFCTR_X86_INTEL_PIII:
Packit 577717
      case PERFCTR_X86_CYRIX_MII:
Packit 577717
      case PERFCTR_X86_WINCHIP_C6:
Packit 577717
      case PERFCTR_X86_WINCHIP_2:
Packit 577717
      case PERFCTR_X86_INTEL_PENTM:
Packit 577717
      case PERFCTR_X86_INTEL_CORE:
Packit 577717
	return 2;
Packit 577717
      case PERFCTR_X86_AMD_K7:
Packit 577717
	return 4;
Packit 577717
      case PERFCTR_X86_VIA_C3:
Packit 577717
	return 1;
Packit 577717
      case PERFCTR_X86_INTEL_P4:
Packit 577717
      case PERFCTR_X86_INTEL_P4M2:
Packit 577717
	return 18;
Packit 577717
#endif
Packit 577717
      case PERFCTR_X86_INTEL_P4M3:
Packit 577717
	return 18;
Packit 577717
      case PERFCTR_X86_AMD_K8:
Packit 577717
      case PERFCTR_X86_AMD_K8C:
Packit 577717
      case PERFCTR_X86_AMD_FAM10H:
Packit 577717
	return 4;
Packit 577717
      case PERFCTR_X86_INTEL_CORE2:
Packit 577717
	return 5;
Packit 577717
      case PERFCTR_X86_INTEL_ATOM:
Packit 577717
	return atom_nrctrs();
Packit 577717
      case PERFCTR_X86_INTEL_NHLM:
Packit 577717
      case PERFCTR_X86_INTEL_WSTMR:
Packit 577717
	return 7;
Packit 577717
      case PERFCTR_X86_GENERIC:
Packit 577717
      default:
Packit 577717
	return 0;
Packit 577717
    }
Packit 577717
}
Packit 577717
Packit 577717
const char *perfctr_info_cpu_name(const struct perfctr_info *info)
Packit 577717
{
Packit 577717
    switch (info->cpu_type) {
Packit 577717
      case PERFCTR_X86_GENERIC:
Packit 577717
	return "Generic x86 with TSC";
Packit 577717
#if !defined(__x86_64__)
Packit 577717
      case PERFCTR_X86_INTEL_P5:
Packit 577717
        return "Intel Pentium";
Packit 577717
      case PERFCTR_X86_INTEL_P5MMX:
Packit 577717
        return "Intel Pentium MMX";
Packit 577717
      case PERFCTR_X86_INTEL_P6:
Packit 577717
        return "Intel Pentium Pro";
Packit 577717
      case PERFCTR_X86_INTEL_PII:
Packit 577717
        return "Intel Pentium II";
Packit 577717
      case PERFCTR_X86_INTEL_PIII:
Packit 577717
        return "Intel Pentium III";
Packit 577717
      case PERFCTR_X86_CYRIX_MII:
Packit 577717
        return "Cyrix 6x86MX/MII/III";
Packit 577717
      case PERFCTR_X86_WINCHIP_C6:
Packit 577717
	return "WinChip C6";
Packit 577717
      case PERFCTR_X86_WINCHIP_2:
Packit 577717
	return "WinChip 2/3";
Packit 577717
      case PERFCTR_X86_AMD_K7:
Packit 577717
	return "AMD K7";
Packit 577717
      case PERFCTR_X86_VIA_C3:
Packit 577717
	return "VIA C3";
Packit 577717
      case PERFCTR_X86_INTEL_P4:
Packit 577717
	return "Intel Pentium 4";
Packit 577717
      case PERFCTR_X86_INTEL_P4M2:
Packit 577717
	return "Intel Pentium 4 Model 2";
Packit 577717
      case PERFCTR_X86_INTEL_PENTM:
Packit 577717
	return "Intel Pentium M";
Packit 577717
      case PERFCTR_X86_INTEL_CORE:
Packit 577717
	return "Intel Core";
Packit 577717
#endif
Packit 577717
      case PERFCTR_X86_INTEL_CORE2:
Packit 577717
	return "Intel Core 2";
Packit 577717
      case PERFCTR_X86_INTEL_P4M3:
Packit 577717
	return "Intel Pentium 4 Model 3";
Packit 577717
      case PERFCTR_X86_AMD_K8:
Packit 577717
	return "AMD K8";
Packit 577717
      case PERFCTR_X86_AMD_K8C:
Packit 577717
	return "AMD K8 Revision C";
Packit 577717
      case PERFCTR_X86_AMD_FAM10H:
Packit 577717
	return "AMD Family 10h";
Packit 577717
      case PERFCTR_X86_INTEL_ATOM:
Packit 577717
	return "Intel Atom";
Packit 577717
      case PERFCTR_X86_INTEL_NHLM:
Packit 577717
	return "Intel Nehalem";
Packit 577717
      case PERFCTR_X86_INTEL_WSTMR:
Packit 577717
	return "Intel Westmere";
Packit 577717
      default:
Packit 577717
        return "?";
Packit 577717
    }
Packit 577717
}
Packit 577717
Packit 577717
void perfctr_cpu_control_print(const struct perfctr_cpu_control *control)
Packit 577717
{
Packit 577717
    unsigned int i, nractrs, nrictrs, nrctrs;
Packit 577717
Packit 577717
    nractrs = control->nractrs;
Packit 577717
    nrictrs = control->nrictrs;
Packit 577717
    nrctrs = control->nractrs + nrictrs;
Packit 577717
Packit 577717
    printf("tsc_on\t\t\t%u\n", control->tsc_on);
Packit 577717
    printf("nractrs\t\t\t%u\n", nractrs);
Packit 577717
    if (nrictrs)
Packit 577717
	printf("nrictrs\t\t\t%u\n", nrictrs);
Packit 577717
    for(i = 0; i < nrctrs; ++i) {
Packit 577717
        if (control->pmc_map[i] >= 18) /* for Core2 fixed counters or P4 fast rdpmc */
Packit 577717
            printf("pmc_map[%u]\t\t0x%08X\n", i, control->pmc_map[i]);
Packit 577717
        else
Packit 577717
            printf("pmc_map[%u]\t\t%u\n", i, control->pmc_map[i]);
Packit 577717
        printf("evntsel[%u]\t\t0x%08X\n", i, control->evntsel[i]);
Packit 577717
        if (control->p4.escr[i])
Packit 577717
            printf("escr[%u]\t\t\t0x%08X\n", i, control->p4.escr[i]);
Packit 577717
	if (i >= nractrs)
Packit 577717
	    printf("ireset[%u]\t\t%d\n", i, control->ireset[i]);
Packit 577717
    }
Packit 577717
    if (control->p4.pebs_enable)
Packit 577717
	printf("pebs_enable\t\t0x%08X\n", control->p4.pebs_enable);
Packit 577717
    if (control->p4.pebs_matrix_vert)
Packit 577717
	printf("pebs_matrix_vert\t0x%08X\n", control->p4.pebs_matrix_vert);
Packit 577717
}