more clean ups, some ppc stuff
[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
32 #ifdef __alpha__
33   char model_id[80], system_id[80], serial_number[80];
34   unsigned cpu_variation, cpu_revision, u;
35   cpu_info_t *ct1;
36 #endif
37
38 #ifdef __PPC__
39   char model_id[80], system_id[80], serial_number[80];
40   unsigned cpu_variation, cpu_revision;
41 #endif
42
43   if(!hd_probe_feature(hd_data, pr_cpu)) return;
44
45   hd_data->module = mod_cpu;
46
47   /* some clean-up */
48   remove_hd_entries(hd_data);
49   hd_data->cpu = NULL;
50
51   PROGRESS(1, 0, "cpuinfo");
52
53   hd_data->cpu = read_file(PROC_CPUINFO, 0, 0);
54   if((hd_data->debug & HD_DEB_CPU)) dump_cpu_data(hd_data);
55   if(!hd_data->cpu) return;
56
57 #ifdef __alpha__
58   *model_id = *system_id = *serial_number = 0;
59   cpu_variation = cpu_revision = 0;
60   cpus = 1;
61
62   for(sl = hd_data->cpu; sl; sl = sl->next) {
63     if(sscanf(sl->str, "cpu model : %79[^\n]", model_id) == 1) continue;
64     if(sscanf(sl->str, "system type : %79[^\n]", system_id) == 1) continue;
65     if(sscanf(sl->str, "cpu variation : %u", &cpu_variation) == 1) continue;
66     if(sscanf(sl->str, "cpu revision : %u", &cpu_revision) == 1) continue;
67     if(sscanf(sl->str, "system serial number : %79[^\n]", serial_number) == 1) continue;
68     if(sscanf(sl->str, "cpus detected : %u", &cpus) == 1) continue;
69   }
70
71   if(*model_id || *system_id) { /* at least one of those */
72     ct = new_mem(sizeof *ct);
73     ct->architecture = arch_alpha;
74     if(model_id) ct->model_name = new_str(model_id);
75     if(system_id) ct->vend_name = new_str(system_id);
76     if(strncmp(serial_number, "MILO", 4) == 0)
77       ct->boot = boot_milo;
78     else
79       ct->boot = boot_aboot;
80
81     ct->family = cpu_variation;
82     ct->model = cpu_revision;
83     ct->stepping = 0;
84     ct->cache = 0;
85     ct->clock = 0;
86
87     for(u = 0; u < cpus; u++) {
88       hd = add_hd_entry(hd_data, __LINE__, 0);
89       hd->base_class = bc_internal;
90       hd->sub_class = sc_int_cpu;
91       hd->slot = u;
92       hd->detail = new_mem(sizeof *hd->detail);
93       hd->detail->type = hd_detail_cpu;
94       if(u) {
95         hd->detail->cpu.data = ct1 = new_mem(sizeof *ct);
96         *ct1 = *ct;
97         ct1->model_name = new_str(ct1->model_name);
98         ct1->vend_name = new_str(ct1->vend_name);
99       }
100       else {
101         hd->detail->cpu.data = ct;
102       }
103     }
104
105   }
106 #endif
107
108 #ifdef __sparc__
109 #endif
110
111
112 /* Intel code  */
113
114 #ifdef __i386__
115   *model_id = *vendor_id = 0;
116   bogo = mhz = cache = family = model= 0;
117
118   for(sl = hd_data->cpu; sl; sl = sl->next) {
119     if(sscanf(sl->str, "model name : %79[^\n]", model_id) == 1) continue;
120     if(sscanf(sl->str, "vendor_id : %79[^\n]", vendor_id) == 1) continue;
121     if(sscanf(sl->str, "bogomips : %u", &bogo) == 1) continue;
122     if(sscanf(sl->str, "cpu MHz : %u", &mhz) == 1) continue;
123     if(sscanf(sl->str, "cache size : %u KB", &cache) == 1) continue;
124
125     if(sscanf(sl->str, "cpu family : %u", &family) == 1) continue;
126     if(sscanf(sl->str, "model : %u", &model) == 1) continue;
127     if(sscanf(sl->str, "stepping : %u", &stepping) == 1) continue;
128
129     if(strstr(sl->str, "processor") == sl->str || !sl->next) {          /* EOF */
130       if(*model_id || *vendor_id) {     /* at least one of those */
131         ct = new_mem(sizeof *ct);
132         ct->architecture = arch_intel;
133         if(model_id) ct->model_name = new_str(model_id);
134         if(vendor_id) ct->vend_name = new_str(vendor_id);
135         ct->family = family;
136         ct->model = model;
137         ct->stepping = stepping;
138         ct->cache = cache;
139         ct->boot = boot_lilo;
140
141         /* round clock to typical values */
142         if(mhz >= 38 && mhz <= 42)
143           mhz = 40;
144         else if(mhz >= 88 && mhz <= 92)
145           mhz = 90;
146         else {
147           unsigned u, v;
148
149           u = (mhz + 2) % 100;
150           v = (mhz + 2) / 100;
151           if(u <= 4)
152             u = 2;
153           else if(u >= 25 && u <= 29)
154             u = 25 + 2;
155           else if(u >= 33 && u <= 37)
156             u = 33 + 2;
157           else if(u >= 50 && u <= 54)
158             u = 50 + 2;
159           else if(u >= 66 && u <= 70)
160             u = 66 + 2;
161           else if(u >= 75 && u <= 79)
162             u = 75 + 2;
163           else if(u >= 80 && u <= 84)   /* there are 180MHz PPros */
164             u = 80 + 2;
165           u -= 2;
166           mhz = v * 100 + u;
167         }
168
169         ct->clock = mhz;
170
171         hd = add_hd_entry(hd_data, __LINE__, 0);
172         hd->base_class = bc_internal;
173         hd->sub_class = sc_int_cpu;
174         hd->slot = cpus;
175         hd->detail = new_mem(sizeof *hd->detail);
176         hd->detail->type = hd_detail_cpu;
177         hd->detail->cpu.data = ct;
178         
179         *model_id = *vendor_id = 0;
180         bogo = mhz = cache = family = model= 0;
181         cpus++;
182       }
183     }
184   }
185 #endif /* __i386__  */
186
187 #ifdef __PPC__
188   *model_id = *vendor_id = 0;
189   bogo = mhz = cache = family = model= 0;
190
191   for(sl = hd_data->cpu; sl; sl = sl->next) {
192     if(sscanf(sl->str, "cpu : %79[^\n]", model_id) == 1) continue;
193 //    if(sscanf(sl->str, "vendor_id : %79[^\n]", vendor_id) == 1) continue;
194     if(sscanf(sl->str, "bogomips : %u", &bogo) == 1) continue;
195     if(sscanf(sl->str, "clock : %u", &mhz) == 1) continue;
196     if(sscanf(sl->str, "L2 cache : %u KB", &cache) == 1) continue;
197
198 //    if(sscanf(sl->str, "cpu family : %u", &family) == 1) continue;
199 //    if(sscanf(sl->str, "model : %u", &model) == 1) continue;
200 //    if(sscanf(sl->str, "stepping : %u", &stepping) == 1) continue;
201
202     if(strstr(sl->str, "processor") == sl->str || !sl->next) {          /* EOF */
203       if(*model_id || *vendor_id) {     /* at least one of those */
204         ct = new_mem(sizeof *ct);
205         ct->architecture = arch_ppc;
206         if(model_id) ct->model_name = new_str(model_id);
207         if(vendor_id) ct->vend_name = new_str(vendor_id);
208         ct->family = family;
209         ct->model = model;
210         ct->stepping = stepping;
211         ct->cache = cache;
212         ct->boot = boot_unknown;
213         ct->clock = mhz;
214
215         hd = add_hd_entry(hd_data, __LINE__, 0);
216         hd->base_class = bc_internal;
217         hd->sub_class = sc_int_cpu;
218         hd->slot = cpus;
219         hd->detail = new_mem(sizeof *hd->detail);
220         hd->detail->type = hd_detail_cpu;
221         hd->detail->cpu.data = ct;
222         
223         *model_id = *vendor_id = 0;
224         bogo = mhz = cache = family = model= 0;
225         cpus++;
226       }
227     }
228   }
229 #endif /* __PPC__  */
230
231 }
232
233
234 /*
235  * Add some cpu data to the global log.
236  */
237 void dump_cpu_data(hd_data_t *hd_data)
238 {
239   str_list_t *sl;
240
241   ADD2LOG("----- /proc/cpuinfo -----\n");
242   for(sl = hd_data->cpu; sl; sl = sl->next) {
243     ADD2LOG("  %s", sl->str);
244   }
245   ADD2LOG("----- /proc/cpuinfo end -----\n");
246 }
247