Initial revision
[opensuse:hwinfo.git] / src / hd / cpu.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "hd.h"
6 #include "hd_int.h"
7 #include "cpu.h"
8
9 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10  * cpu info
11  *
12  * Note: on other architectures, entries differ (cf. Alpha)!!!
13  *
14  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15  */
16
17
18 static void dump_cpu_data(hd_data_t *hd_data);
19
20 void hd_scan_cpu(hd_data_t *hd_data)
21 {
22   hd_t *hd;
23   unsigned cpus = 0;
24   cpu_info_t *ct;
25   str_list_t *sl;
26
27 #ifdef __i386__
28   char model_id[80], vendor_id[80];
29   unsigned bogo, mhz, cache, family, model, stepping;
30 #endif
31 #ifdef __alpha__
32   char model_id[80], system_id[80], serial_number[80];
33   unsigned cpu_variation, cpu_revision;
34 #endif
35
36   if(!(hd_data->probe & (1 << pr_cpu))) return;
37
38   hd_data->module = mod_cpu;
39
40   /* some clean-up */
41   remove_hd_entries(hd_data);
42   hd_data->cpu = NULL;
43
44   PROGRESS(1, 0, "cpuinfo");
45
46   hd_data->cpu = read_file(PROC_CPUINFO, 0, 0);
47   if((hd_data->debug & HD_DEB_CPU)) dump_cpu_data(hd_data);
48   if(!hd_data->cpu) return;
49
50 #ifdef __alpha__
51   *model_id = *system_id = *serial_number = 0;
52   cpu_variation = cpu_revision = 0;
53   cpus = 1;
54
55   for(sl = hd_data->cpu; sl; sl = sl->next) {
56     if(sscanf(sl->str, "cpu model : %79[^\n]", model_id) == 1) continue;
57     if(sscanf(sl->str, "system type : %79[^\n]", system_id) == 1) continue;
58     if(sscanf(sl->str, "cpu variation : %u", &cpu_variation) == 1) continue;
59     if(sscanf(sl->str, "cpu revision : %u", &cpu_revision) == 1) continue;
60     if(sscanf(sl->str, "system serial number : %79[^\n]", serial_number) == 1) continue;
61     if(sscanf(sl->str, "cpus detected : %u", &cpus) == 1) continue;
62   }
63
64   if(*model_id || *system_id) { /* at least one of those */
65     ct = new_mem(sizeof *ct);
66     ct->architecture = arch_alpha;
67     if(model_id) ct->model_name = new_str(model_id);
68     if(system_id) ct->vend_name = new_str(system_id);
69     if(strncmp(serial_number, "MILO", 4) == 0)
70       ct->boot = boot_milo;
71     else
72       ct->boot = boot_aboot;
73
74     ct->family = cpu_variation;
75     ct->model = cpu_revision;
76     ct->stepping = 0;
77     ct->cache = 0;
78     ct->clock = 0;
79
80     hd = add_hd_entry(hd_data, __LINE__, 0);
81     hd->base_class = bc_internal;
82     hd->sub_class = sc_int_cpu;
83     hd->slot = cpus;
84     hd->detail = new_mem(sizeof *hd->detail);
85     hd->detail->type = hd_detail_cpu;
86     hd->detail->cpu.data = ct;
87
88     *model_id = *system_id = *serial_number = 0;
89     cpu_variation = cpu_revision = 0;
90   }
91 #endif
92
93 #ifdef __sparc__
94 #endif
95
96
97 /* Intel code  */
98
99 #ifdef __i386__
100   *model_id = *vendor_id = 0;
101   bogo = mhz = cache = family = model= 0;
102
103   for(sl = hd_data->cpu; sl; sl = sl->next) {
104     if(sscanf(sl->str, "model name : %79[^\n]", model_id) == 1) continue;
105     if(sscanf(sl->str, "vendor_id : %79[^\n]", vendor_id) == 1) continue;
106     if(sscanf(sl->str, "bogomips : %u", &bogo) == 1) continue;
107     if(sscanf(sl->str, "cpu MHz : %u", &mhz) == 1) continue;
108     if(sscanf(sl->str, "cache size : %u KB", &cache) == 1) continue;
109
110     if(sscanf(sl->str, "cpu family : %u", &family) == 1) continue;
111     if(sscanf(sl->str, "model : %u", &model) == 1) continue;
112     if(sscanf(sl->str, "stepping : %u", &stepping) == 1) continue;
113
114     if(strstr(sl->str, "processor") == sl->str || !sl->next) {          /* EOF */
115       if(*model_id || *vendor_id) {     /* at least one of those */
116         ct = new_mem(sizeof *ct);
117         ct->architecture = arch_intel;
118         if(model_id) ct->model_name = new_str(model_id);
119         if(vendor_id) ct->vend_name = new_str(vendor_id);
120         ct->family = family;
121         ct->model = model;
122         ct->stepping = stepping;
123         ct->cache = cache;
124         ct->boot = boot_lilo;
125
126         /* round clock to typical values */
127         if(mhz >= 38 && mhz <= 42)
128           mhz = 40;
129         else if(mhz >= 88 && mhz <= 92)
130           mhz = 90;
131         else {
132           unsigned u, v;
133
134           u = (mhz + 2) % 100;
135           v = (mhz + 2) / 100;
136           if(u <= 4)
137             u = 2;
138           else if(u >= 25 && u <= 29)
139             u = 25 + 2;
140           else if(u >= 33 && u <= 37)
141             u = 33 + 2;
142           else if(u >= 50 && u <= 54)
143             u = 50 + 2;
144           else if(u >= 66 && u <= 70)
145             u = 66 + 2;
146           else if(u >= 75 && u <= 79)
147             u = 75 + 2;
148           else if(u >= 80 && u <= 84)   /* there are 180MHz PPros */
149             u = 80 + 2;
150           u -= 2;
151           mhz = v * 100 + u;
152         }
153
154         ct->clock = mhz;
155
156         hd = add_hd_entry(hd_data, __LINE__, 0);
157         hd->base_class = bc_internal;
158         hd->sub_class = sc_int_cpu;
159         hd->slot = cpus;
160         hd->detail = new_mem(sizeof *hd->detail);
161         hd->detail->type = hd_detail_cpu;
162         hd->detail->cpu.data = ct;
163         
164         *model_id = *vendor_id = 0;
165         bogo = mhz = cache = family = model= 0;
166         cpus++;
167       }
168     }
169   }
170 #endif /* __i386__  */
171
172 }
173
174
175 /*
176  * Add some cpu data to the global log.
177  */
178 void dump_cpu_data(hd_data_t *hd_data)
179 {
180   str_list_t *sl;
181
182   ADD2LOG("----- /proc/cpuinfo -----\n");
183   for(sl = hd_data->cpu; sl; sl = sl->next) {
184     ADD2LOG("  %s", sl->str);
185   }
186   ADD2LOG("----- /proc/cpuinfo end -----\n");
187 }
188