Blame src/perfctr-2.7.x/usr.lib/x86_cpuinfo.c

Packit 577717
/* $Id: x86_cpuinfo.c,v 1.1 2004/05/22 20:59:58 mikpe Exp $
Packit 577717
 * Copyright (C) 2004  Mikael Pettersson
Packit 577717
 */
Packit 577717
#include <string.h>
Packit 577717
#include "x86_cpuinfo.h"
Packit 577717
Packit 577717
struct cpuid { /* The field order must not be changed. */
Packit 577717
    unsigned int eax, ebx, edx, ecx;
Packit 577717
};
Packit 577717
Packit 577717
#ifdef __x86_64__
Packit 577717
static void get_cpuid(unsigned int op, struct cpuid *cpuid)
Packit 577717
{
Packit 577717
    __asm__("cpuid"
Packit 577717
	    : "=a"(cpuid->eax),
Packit 577717
	      "=b"(cpuid->ebx),
Packit 577717
	      "=c"(cpuid->ecx),
Packit 577717
	      "=d"(cpuid->edx)
Packit 577717
	    : "0"(op));
Packit 577717
}
Packit 577717
#else
Packit 577717
/* Many versions of gcc fail on x86 if an asm() clobbers %ebx when
Packit 577717
   -fPIC is specified. So we do the cpuid in hand-written assembly code. */
Packit 577717
extern void get_cpuid(unsigned int, struct cpuid*); /* x86_cpuid.S */
Packit 577717
#endif
Packit 577717
Packit 577717
static const struct {
Packit 577717
    const char vendor_string[12];
Packit 577717
    unsigned int vendor_code;
Packit 577717
} vendors[] = {
Packit 577717
    { "GenuineIntel", X86_VENDOR_INTEL },
Packit 577717
    { "AuthenticAMD", X86_VENDOR_AMD },
Packit 577717
    { "CyrixInstead", X86_VENDOR_CYRIX },
Packit 577717
    { "CentaurHauls", X86_VENDOR_CENTAUR },
Packit 577717
};
Packit 577717
Packit 577717
static unsigned int check_vendor(const char cpuid_vendor[12])
Packit 577717
{
Packit 577717
    int i;
Packit 577717
Packit 577717
    for(i = 0; i < sizeof vendors / sizeof(vendors[0]); ++i)
Packit 577717
        if (memcmp(cpuid_vendor, vendors[i].vendor_string, 12) == 0)
Packit 577717
            return vendors[i].vendor_code;
Packit 577717
    return X86_VENDOR_UNKNOWN;
Packit 577717
}
Packit 577717
Packit 577717
void identify_cpu(struct cpuinfo *cpuinfo)
Packit 577717
{
Packit 577717
    struct cpuid cpuid[2];
Packit 577717
Packit 577717
    /* Skip EFLAGS.ID check. We will only get here if
Packit 577717
       the kernel has created a perfctr state for us,
Packit 577717
       and that will never happen on pre-CPUID CPUs. */
Packit 577717
Packit 577717
    get_cpuid(0, &cpuid[0]);
Packit 577717
Packit 577717
    /* Quirk for Intel A-step Pentium. */
Packit 577717
    if ((cpuid[0].eax & 0xFFFFFF00) == 0x0500) {
Packit 577717
	cpuinfo->vendor = X86_VENDOR_INTEL;
Packit 577717
	cpuinfo->signature = cpuid[0].eax;
Packit 577717
	cpuinfo->features = 0x1BF; /* CX8,MCE,MSR,TSC,PSE,DE,VME,FPU */
Packit 577717
	return;
Packit 577717
    }
Packit 577717
Packit 577717
    cpuinfo->vendor = check_vendor((const char*)&cpuid[0].ebx);
Packit 577717
Packit 577717
    if (cpuid[0].eax == 0) {
Packit 577717
	cpuinfo->signature = 0;
Packit 577717
	cpuinfo->features = 0;
Packit 577717
    } else {
Packit 577717
	get_cpuid(1, &cpuid[1]);
Packit 577717
	cpuinfo->signature = cpuid[1].eax;
Packit 577717
	cpuinfo->features = cpuid[1].edx;
Packit 577717
    }
Packit 577717
}