op_cpu_type.c revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/** 2 * @file op_cpu_type.c 3 * CPU type determination 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12#include <stdio.h> 13#include <stdlib.h> 14#include <string.h> 15 16#include "op_cpu_type.h" 17 18struct cpu_descr { 19 char const * pretty; 20 char const * name; 21 op_cpu cpu; 22 unsigned int nr_counters; 23}; 24 25static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = { 26 { "Pentium Pro", "i386/ppro", CPU_PPRO, 2 }, 27 { "PII", "i386/pii", CPU_PII, 2 }, 28 { "PIII", "i386/piii", CPU_PIII, 2 }, 29 { "Athlon", "i386/athlon", CPU_ATHLON, 4 }, 30 { "CPU with timer interrupt", "timer", CPU_TIMER_INT, 1 }, 31 { "CPU with RTC device", "rtc", CPU_RTC, 1 }, 32 { "P4 / Xeon", "i386/p4", CPU_P4, 8 }, 33 { "IA64", "ia64/ia64", CPU_IA64, 4 }, 34 { "Itanium", "ia64/itanium", CPU_IA64_1, 4 }, 35 { "Itanium 2", "ia64/itanium2", CPU_IA64_2, 4 }, 36 { "AMD64 processors", "x86-64/hammer", CPU_HAMMER, 4 }, 37 { "P4 / Xeon with 2 hyper-threads", "i386/p4-ht", CPU_P4_HT2, 4 }, 38 { "Alpha EV4", "alpha/ev4", CPU_AXP_EV4, 2 }, 39 { "Alpha EV5", "alpha/ev5", CPU_AXP_EV5, 3 }, 40 { "Alpha PCA56", "alpha/pca56", CPU_AXP_PCA56, 3 }, 41 { "Alpha EV6", "alpha/ev6", CPU_AXP_EV6, 2 }, 42 { "Alpha EV67", "alpha/ev67", CPU_AXP_EV67, 20 }, 43 { "Pentium M (P6 core)", "i386/p6_mobile", CPU_P6_MOBILE, 2 }, 44 { "ARM/XScale PMU1", "arm/xscale1", CPU_ARM_XSCALE1, 3 }, 45 { "ARM/XScale PMU2", "arm/xscale2", CPU_ARM_XSCALE2, 5 }, 46 { "ppc64 POWER4", "ppc64/power4", CPU_PPC64_POWER4, 8 }, 47 { "ppc64 POWER5", "ppc64/power5", CPU_PPC64_POWER5, 6 }, 48 { "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 }, 49 { "MIPS 24K", "mips/24K", CPU_MIPS_24K, 2}, 50 { "MIPS R10000", "mips/r10000", CPU_MIPS_R10000, 2 }, 51 { "MIPS R12000", "mips/r12000", CPU_MIPS_R12000, 4 }, 52 { "QED RM7000", "mips/rm7000", CPU_MIPS_RM7000, 1 }, 53 { "PMC-Sierra RM9000", "mips/rm9000", CPU_MIPS_RM9000, 2 }, 54 { "Sibyte SB1", "mips/sb1", CPU_MIPS_SB1, 4 }, 55 { "NEC VR5432", "mips/vr5432", CPU_MIPS_VR5432, 2 }, 56 { "NEC VR5500", "mips/vr5500", CPU_MIPS_VR5500, 2 }, 57 { "e500", "ppc/e500", CPU_PPC_E500, 4 }, 58}; 59 60static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr); 61 62op_cpu op_get_cpu_type(void) 63{ 64 int cpu_type = CPU_NO_GOOD; 65 char str[100]; 66 FILE * fp; 67 68 fp = fopen("/proc/sys/dev/oprofile/cpu_type", "r"); 69 if (!fp) { 70 /* Try 2.6's oprofilefs one instead. */ 71 fp = fopen("/dev/oprofile/cpu_type", "r"); 72 if (!fp) { 73 fprintf(stderr, "Unable to open cpu_type file for reading\n"); 74 fprintf(stderr, "Make sure you have done opcontrol --init\n"); 75 return cpu_type; 76 } 77 } 78 79 if (!fgets(str, 99, fp)) { 80 fprintf(stderr, "Could not read cpu type.\n"); 81 return CPU_NO_GOOD; 82 } 83 84 cpu_type = op_get_cpu_number(str); 85 86 fclose(fp); 87 88 return cpu_type; 89} 90 91 92op_cpu op_get_cpu_number(char const * cpu_string) 93{ 94 int cpu_type = CPU_NO_GOOD; 95 size_t i; 96 97 for (i = 0; i < nr_cpu_descrs; ++i) { 98 if (!strcmp(cpu_descrs[i].name, cpu_string)) { 99 cpu_type = cpu_descrs[i].cpu; 100 break; 101 } 102 } 103 104 /* Attempt to convert into a number */ 105 if (cpu_type == CPU_NO_GOOD) 106 sscanf(cpu_string, "%d\n", &cpu_type); 107 108 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) 109 cpu_type = CPU_NO_GOOD; 110 111 return cpu_type; 112} 113 114 115char const * op_get_cpu_type_str(op_cpu cpu_type) 116{ 117 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) 118 return "invalid cpu type"; 119 120 return cpu_descrs[cpu_type].pretty; 121} 122 123 124char const * op_get_cpu_name(op_cpu cpu_type) 125{ 126 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) 127 return "invalid cpu type"; 128 129 return cpu_descrs[cpu_type].name; 130} 131 132 133int op_get_nr_counters(op_cpu cpu_type) 134{ 135 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE) 136 return 0; 137 138 return cpu_descrs[cpu_type].nr_counters; 139} 140