1 | diff -Naur coreutils-6.9.orig/src/uname.c coreutils-6.9/src/uname.c
|
---|
2 | --- coreutils-6.9.orig/src/uname.c 2007-03-18 21:36:43.000000000 +0000
|
---|
3 | +++ coreutils-6.9/src/uname.c 2007-04-17 19:34:32.000000000 +0000
|
---|
4 | @@ -51,6 +51,31 @@
|
---|
5 | # include <mach-o/arch.h>
|
---|
6 | #endif
|
---|
7 |
|
---|
8 | +#if defined(__linux__)
|
---|
9 | +/* Thanks to the ffmpeg libavcodec/i386/cputest.c for this PIC version of cpuid() */
|
---|
10 | +# if defined(__i386__)
|
---|
11 | +# define REG_b "ebx"
|
---|
12 | +# define REG_S "esi"
|
---|
13 | +# elif defined(__x86_64__)
|
---|
14 | +# define REG_b "rbx"
|
---|
15 | +# define REG_S "rsi"
|
---|
16 | +# endif
|
---|
17 | +# if defined(REG_b) && defined(REG_S)
|
---|
18 | +# define x86cpuid(index,eax,ebx,ecx,edx)\
|
---|
19 | + __asm __volatile\
|
---|
20 | + ("mov %%"REG_b", %%"REG_S"\n\t"\
|
---|
21 | + "cpuid\n\t"\
|
---|
22 | + "xchg %%"REG_b", %%"REG_S\
|
---|
23 | + : "=a" (eax), "=S" (ebx),\
|
---|
24 | + "=c" (ecx), "=d" (edx)\
|
---|
25 | + : "0" (index));
|
---|
26 | +int has_sse(void);
|
---|
27 | +# else /* Not an x86? Then try /proc/{sys,cpu}info. */
|
---|
28 | +# define USE_PROCINFO
|
---|
29 | +# define UNAME_HARDWARE_PLATFORM
|
---|
30 | +# endif
|
---|
31 | +#endif /* __linux__ */
|
---|
32 | +
|
---|
33 | #include "system.h"
|
---|
34 | #include "error.h"
|
---|
35 | #include "quote.h"
|
---|
36 | @@ -138,6 +163,108 @@
|
---|
37 | exit (status);
|
---|
38 | }
|
---|
39 |
|
---|
40 | +#if defined(USE_PROCINFO)
|
---|
41 | +
|
---|
42 | +# if defined(__s390__) || defined(__s390x__)
|
---|
43 | +# define CPUINFO_FILE "/proc/sysinfo"
|
---|
44 | +# define CPUINFO_FORMAT "%64[^\t :]%*[ :]%256[^\n]%c"
|
---|
45 | +# else
|
---|
46 | +# define CPUINFO_FILE "/proc/cpuinfo"
|
---|
47 | +# define CPUINFO_FORMAT "%64[^\t:]\t:%256[^\n]%c"
|
---|
48 | +# endif
|
---|
49 | +
|
---|
50 | +# define PROCINFO_PROCESSOR 0
|
---|
51 | +# define PROCINFO_HARDWARE_PLATFORM 1
|
---|
52 | +
|
---|
53 | +static void __eat_cpuinfo_space(char *buf)
|
---|
54 | +{
|
---|
55 | + /* first eat trailing space */
|
---|
56 | + char *tmp = buf + strlen(buf) - 1;
|
---|
57 | + while (tmp > buf && isspace(*tmp))
|
---|
58 | + *tmp-- = '\0';
|
---|
59 | + /* then eat leading space */
|
---|
60 | + tmp = buf;
|
---|
61 | + while (*tmp && isspace(*tmp))
|
---|
62 | + tmp++;
|
---|
63 | + if (tmp != buf)
|
---|
64 | + memmove(buf, tmp, strlen(tmp)+1);
|
---|
65 | +}
|
---|
66 | +
|
---|
67 | +static int __linux_procinfo (int x, char *fstr, size_t s)
|
---|
68 | +{
|
---|
69 | + FILE *fp;
|
---|
70 | +
|
---|
71 | + char *procinfo_keys[] = {
|
---|
72 | + /* --processor --hardware-platform */
|
---|
73 | + #if defined(__alpha__)
|
---|
74 | + "cpu model", "system type"
|
---|
75 | + #elif defined(__arm__)
|
---|
76 | + "Processor", "Hardware"
|
---|
77 | + #elif defined(bfin)
|
---|
78 | + "CPU", "BOARD Name"
|
---|
79 | + #elif defined(__cris__)
|
---|
80 | + "cpu", "cpu model"
|
---|
81 | + #elif defined(__frv__)
|
---|
82 | + "CPU-Core", "System"
|
---|
83 | + /*
|
---|
84 | + #elif defined(__i386__) || defined(__x86_64__)
|
---|
85 | + "model name", "vendor_id"
|
---|
86 | + */
|
---|
87 | + #elif defined(__ia64__)
|
---|
88 | + "family", "vendor"
|
---|
89 | + #elif defined(__hppa__)
|
---|
90 | + "cpu", "model"
|
---|
91 | + #elif defined(__m68k__)
|
---|
92 | + "CPU", "MMU"
|
---|
93 | + #elif defined(__mips__)
|
---|
94 | + "cpu model", "system type"
|
---|
95 | + #elif defined(__powerpc__) || defined(__powerpc64__)
|
---|
96 | + "cpu", "machine"
|
---|
97 | + #elif defined(__s390__) || defined(__s390x__)
|
---|
98 | + "Type", "Manufacturer"
|
---|
99 | + #elif defined(__sh__)
|
---|
100 | + "cpu type", "machine"
|
---|
101 | + #elif defined(sparc) || defined(__sparc__)
|
---|
102 | + "type", "cpu"
|
---|
103 | + #elif defined(__vax__)
|
---|
104 | + "cpu type", "cpu"
|
---|
105 | + #else
|
---|
106 | + "unknown", "unknown"
|
---|
107 | + #endif
|
---|
108 | + };
|
---|
109 | +
|
---|
110 | + if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
|
---|
111 | + char key[65], value[257], eol, *ret = NULL;
|
---|
112 | +
|
---|
113 | + while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
|
---|
114 | + __eat_cpuinfo_space(key);
|
---|
115 | + if (!strcmp(key, procinfo_keys[x])) {
|
---|
116 | + __eat_cpuinfo_space(value);
|
---|
117 | + ret = value;
|
---|
118 | + break;
|
---|
119 | + }
|
---|
120 | + if (eol != '\n') {
|
---|
121 | + /* we need two fscanf's here in case the previous
|
---|
122 | + * length limit caused us to read right up to the
|
---|
123 | + * newline ... doing "%*[^\n]\n" wont eat the newline
|
---|
124 | + */
|
---|
125 | + fscanf(fp, "%*[^\n]");
|
---|
126 | + fscanf(fp, "\n");
|
---|
127 | + }
|
---|
128 | + }
|
---|
129 | + fclose(fp);
|
---|
130 | +
|
---|
131 | + if (ret) {
|
---|
132 | + strncpy(fstr, ret, s);
|
---|
133 | + return 0;
|
---|
134 | + }
|
---|
135 | + }
|
---|
136 | +
|
---|
137 | + return -1;
|
---|
138 | +}
|
---|
139 | +
|
---|
140 | +#endif
|
---|
141 | +
|
---|
142 | /* Print ELEMENT, preceded by a space if something has already been
|
---|
143 | printed. */
|
---|
144 |
|
---|
145 | @@ -250,12 +377,107 @@
|
---|
146 | if (toprint & PRINT_PROCESSOR)
|
---|
147 | {
|
---|
148 | char const *element = unknown;
|
---|
149 | -#if HAVE_SYSINFO && defined SI_ARCHITECTURE
|
---|
150 | +#if (defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)) || defined(USE_PROCINFO)
|
---|
151 | {
|
---|
152 | static char processor[257];
|
---|
153 | +# if defined(USE_PROCINFO)
|
---|
154 | + if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
|
---|
155 | +# else
|
---|
156 | if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
|
---|
157 | +# endif
|
---|
158 | element = processor;
|
---|
159 | }
|
---|
160 | +# elif defined(x86cpuid)
|
---|
161 | + {
|
---|
162 | + struct utsname u;
|
---|
163 | + uname (&u);
|
---|
164 | + element = u.machine;
|
---|
165 | +
|
---|
166 | +/******************************************************************************
|
---|
167 | + *
|
---|
168 | + * Hello, major hack. I shouldn't have to do this. struct utsname should
|
---|
169 | + * have another element with this info in it. There's probably a struct
|
---|
170 | + * somewhere that has this info, I just don't know where it is.
|
---|
171 | + *
|
---|
172 | + *****************************************************************************/
|
---|
173 | +
|
---|
174 | + if( !strcmp( element, "i586" ) || !strcmp( element, "i686" ) ) {
|
---|
175 | + int eax, ebx, ecx, edx, unused;
|
---|
176 | + int model, family, sse;
|
---|
177 | +
|
---|
178 | + x86cpuid(0,unused,ebx,ecx,edx);
|
---|
179 | + x86cpuid(1,eax,unused,unused,unused);
|
---|
180 | + model = (eax >> 4) & 0xf;
|
---|
181 | + family = (eax >> 8) & 0xf;
|
---|
182 | +
|
---|
183 | + switch(ebx) {
|
---|
184 | + case 0x756e6547: /* Intel */
|
---|
185 | + switch( family ) {
|
---|
186 | + case 5: /* Pentium */
|
---|
187 | + if( model <= 3 )
|
---|
188 | + element="pentium";
|
---|
189 | + if( model > 3 )
|
---|
190 | + element="pentium-mmx";
|
---|
191 | + break;
|
---|
192 | + case 6: /* PentiumPro - Pentium3 */
|
---|
193 | + if( model == 1 ) /* Pentium Pro */
|
---|
194 | + element="pentiumpro";
|
---|
195 | + if( ( model == 3 ) || ( model == 5 ) ||
|
---|
196 | + ( model == 6 ) ) /* Pentium II */
|
---|
197 | + element="pentium2";
|
---|
198 | + if( ( model == 7 ) || ( model == 8 ) ||
|
---|
199 | + ( model == 10 ) || ( model == 11 ) ) /* These are all Pentium3 */
|
---|
200 | + element="pentium3";
|
---|
201 | + break;
|
---|
202 | + case 15: /* Pentium4 */
|
---|
203 | + if( model == 3 ) /* Prescott */
|
---|
204 | + element="prescott";
|
---|
205 | + else
|
---|
206 | + element="pentium4";
|
---|
207 | + break;
|
---|
208 | + default:
|
---|
209 | + break;
|
---|
210 | + } // end switch( family )
|
---|
211 | + break;
|
---|
212 | + case 0x68747541: /* AMD */
|
---|
213 | + switch(family) {
|
---|
214 | + case 5:
|
---|
215 | + if( ( model == 0 ) || ( model == 1 ) ||
|
---|
216 | + ( model == 2 ) || ( model == 3 ) ) /* K5 */
|
---|
217 | + element="i586";
|
---|
218 | + if( ( model == 6 ) || ( model == 7 ) ) /* K6 */
|
---|
219 | + element="k6";
|
---|
220 | + if( model == 8 ) /* K6-2 */
|
---|
221 | + element="k6-2";
|
---|
222 | + if( model == 9 ) /* K6-3 */
|
---|
223 | + element="k6-3";
|
---|
224 | + break;
|
---|
225 | + case 6:
|
---|
226 | + if( model <= 4 )
|
---|
227 | + element="athlon";
|
---|
228 | + if( model > 4 ) {
|
---|
229 | + sse = has_sse();
|
---|
230 | + if( sse == 0 )
|
---|
231 | + element="athlon";
|
---|
232 | + if( sse == 1 )
|
---|
233 | + element="athlon-4";
|
---|
234 | + }
|
---|
235 | + break;
|
---|
236 | + case 15:
|
---|
237 | + element="athlon-4";
|
---|
238 | + break;
|
---|
239 | + default:
|
---|
240 | + break;
|
---|
241 | + } /* end switch(family) */
|
---|
242 | + break;
|
---|
243 | + case 0x69727943: /* Cyrix */
|
---|
244 | + element="i386"; /* Who knows what cyrix supports, lets be safe. */
|
---|
245 | + break;
|
---|
246 | + default:
|
---|
247 | + break;
|
---|
248 | + } /* end switch(ebx) */
|
---|
249 | + }
|
---|
250 | + }
|
---|
251 | #endif
|
---|
252 | #ifdef UNAME_PROCESSOR
|
---|
253 | if (element == unknown)
|
---|
254 | @@ -293,7 +515,7 @@
|
---|
255 |
|
---|
256 | if (toprint & PRINT_HARDWARE_PLATFORM)
|
---|
257 | {
|
---|
258 | - char const *element = unknown;
|
---|
259 | + char *element = unknown;
|
---|
260 | #if HAVE_SYSINFO && defined SI_PLATFORM
|
---|
261 | {
|
---|
262 | static char hardware_platform[257];
|
---|
263 | @@ -301,14 +523,27 @@
|
---|
264 | hardware_platform, sizeof hardware_platform))
|
---|
265 | element = hardware_platform;
|
---|
266 | }
|
---|
267 | +#elif defined(x86cpuid)
|
---|
268 | + {
|
---|
269 | + struct utsname u;
|
---|
270 | + uname (&u);
|
---|
271 | + element = u.machine;
|
---|
272 | + if (strlen (element) == 4 && element[0] == 'i' && element[2] == '8'
|
---|
273 | + && element[3] == '6')
|
---|
274 | + element[1] = '3';
|
---|
275 | + }
|
---|
276 | #endif
|
---|
277 | #ifdef UNAME_HARDWARE_PLATFORM
|
---|
278 | if (element == unknown)
|
---|
279 | {
|
---|
280 | static char hardware_platform[257];
|
---|
281 | +#if defined(USE_PROCINFO)
|
---|
282 | + if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
|
---|
283 | +#else
|
---|
284 | size_t s = sizeof hardware_platform;
|
---|
285 | static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
|
---|
286 | if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
|
---|
287 | +#endif
|
---|
288 | element = hardware_platform;
|
---|
289 | }
|
---|
290 | #endif
|
---|
291 | @@ -323,3 +558,29 @@
|
---|
292 |
|
---|
293 | exit (EXIT_SUCCESS);
|
---|
294 | }
|
---|
295 | +
|
---|
296 | +#if defined(x86cpuid)
|
---|
297 | +
|
---|
298 | +/******************************************************************************
|
---|
299 | + *
|
---|
300 | + * int has_sse( void )
|
---|
301 | + * Checks Athlon CPU's to see if they support SSE.
|
---|
302 | + *
|
---|
303 | + *****************************************************************************/
|
---|
304 | +
|
---|
305 | +int has_sse( void )
|
---|
306 | +{
|
---|
307 | + unsigned long edx, unused;
|
---|
308 | + int sse;
|
---|
309 | + x86cpuid(1,unused,unused,unused,edx);
|
---|
310 | + /* I think, I need this tested on a Duron with SSE
|
---|
311 | + and one without it. */
|
---|
312 | + sse = edx & 0x2000000;
|
---|
313 | + if( sse == 0 ) {
|
---|
314 | + return 0;
|
---|
315 | + } else {
|
---|
316 | + return 1;
|
---|
317 | + }
|
---|
318 | +
|
---|
319 | +}
|
---|
320 | +#endif
|
---|