blob: b9d13de13cbfe9c045fb942f925337c5c4c69aad [file] [log] [blame]
The Android Open Source Project10e23ee2009-03-03 19:30:30 -08001/**
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 POWER5+", "ppc64/power5+", CPU_PPC64_POWER5p, 6 },
49 { "ppc64 970", "ppc64/970", CPU_PPC64_970, 8 },
50 { "MIPS 20K", "mips/20K", CPU_MIPS_20K, 1},
51 { "MIPS 24K", "mips/24K", CPU_MIPS_24K, 2},
52 { "MIPS 25K", "mips/25K", CPU_MIPS_25K, 2},
53 { "MIPS 34K", "mips/34K", CPU_MIPS_34K, 4},
54 { "MIPS 5K", "mips/5K", CPU_MIPS_5K, 2},
55 { "MIPS R10000", "mips/r10000", CPU_MIPS_R10000, 2 },
56 { "MIPS R12000", "mips/r12000", CPU_MIPS_R12000, 4 },
57 { "QED RM7000", "mips/rm7000", CPU_MIPS_RM7000, 1 },
58 { "PMC-Sierra RM9000", "mips/rm9000", CPU_MIPS_RM9000, 2 },
59 { "Sibyte SB1", "mips/sb1", CPU_MIPS_SB1, 4 },
60 { "NEC VR5432", "mips/vr5432", CPU_MIPS_VR5432, 2 },
61 { "NEC VR5500", "mips/vr5500", CPU_MIPS_VR5500, 2 },
62 { "e500", "ppc/e500", CPU_PPC_E500, 4 },
63 { "e500v2", "ppc/e500v2", CPU_PPC_E500_2, 4 },
64 { "Core Solo / Duo", "i386/core", CPU_CORE, 2 },
65 { "PowerPC G4", "ppc/7450", CPU_PPC_7450, 6 },
66 { "Core 2", "i386/core_2", CPU_CORE_2, 2 },
67 { "ppc64 POWER6", "ppc64/power6", CPU_PPC64_POWER6, 4 },
68 { "ppc64 970MP", "ppc64/970MP", CPU_PPC64_970MP, 8 },
69 { "ppc64 Cell Broadband Engine", "ppc64/cell-be", CPU_PPC64_CELL, 8 },
70 { "AMD64 family10", "x86-64/family10", CPU_FAMILY10, 4 },
71 { "ppc64 PA6T", "ppc64/pa6t", CPU_PPC64_PA6T, 6 },
72 { "ARM MPCore", "arm/mpcore", CPU_ARM_MPCORE, 2 },
73 { "ARM V6 PMU", "arm/armv6", CPU_ARM_V6, 3 },
74 { "ppc64 POWER5++", "ppc64/power5++", CPU_PPC64_POWER5pp, 6 },
75 { "e300", "ppc/e300", CPU_PPC_E300, 4 },
76 { "AVR32", "avr32", CPU_AVR32, 3 },
77};
78
79static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr);
80
81op_cpu op_get_cpu_type(void)
82{
83 int cpu_type = CPU_NO_GOOD;
84 char str[100];
85 FILE * fp;
86
87 fp = fopen("/proc/sys/dev/oprofile/cpu_type", "r");
88 if (!fp) {
89 /* Try 2.6's oprofilefs one instead. */
90 fp = fopen("/dev/oprofile/cpu_type", "r");
91 if (!fp) {
92 fprintf(stderr, "Unable to open cpu_type file for reading\n");
93 fprintf(stderr, "Make sure you have done opcontrol --init\n");
94 return cpu_type;
95 }
96 }
97
98 if (!fgets(str, 99, fp)) {
99 fprintf(stderr, "Could not read cpu type.\n");
100 return CPU_NO_GOOD;
101 }
102
103 cpu_type = op_get_cpu_number(str);
104
105 fclose(fp);
106
107 return cpu_type;
108}
109
110
111op_cpu op_get_cpu_number(char const * cpu_string)
112{
113 int cpu_type = CPU_NO_GOOD;
114 size_t i;
115
116 for (i = 0; i < nr_cpu_descrs; ++i) {
117 if (!strcmp(cpu_descrs[i].name, cpu_string)) {
118 cpu_type = cpu_descrs[i].cpu;
119 break;
120 }
121 }
122
123 /* Attempt to convert into a number */
124 if (cpu_type == CPU_NO_GOOD)
125 sscanf(cpu_string, "%d\n", &cpu_type);
126
127 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
128 cpu_type = CPU_NO_GOOD;
129
130 return cpu_type;
131}
132
133
134char const * op_get_cpu_type_str(op_cpu cpu_type)
135{
136 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
137 return "invalid cpu type";
138
139 return cpu_descrs[cpu_type].pretty;
140}
141
142
143char const * op_get_cpu_name(op_cpu cpu_type)
144{
145 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
146 return "invalid cpu type";
147
148 return cpu_descrs[cpu_type].name;
149}
150
151
152int op_get_nr_counters(op_cpu cpu_type)
153{
154 if (cpu_type <= CPU_NO_GOOD || cpu_type >= MAX_CPU_TYPE)
155 return 0;
156
157 return cpu_descrs[cpu_type].nr_counters;
158}