| 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
|
|---|