Date: Sat, 03 May 2003 13:54:01 +0100 From: "Richard Dawe" Sender: rich AT phekda DOT freeserve DOT co DOT uk To: djgpp-workers AT delorie DOT com X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: uname and Athlons [PATCH] Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. My desktop PC returns 'athlon' as the machine type, when running RedHat Linux 8.0. I thought it'd be nice for DJGPP to do that too. Below is a patch that makes uname detect Athlons and return the machine type as 'athlon'. After patching and running with a rebuilt uname, the user may need to configure some older packages with the i686-pc-msdosdjgpp triple, rather than it working out-of-the-box. But I don't think that's a major problem. We already have that problem with Pentium 4s. OK to commit? Bye, Rich =] Index: src/libc/posix/utsname/uname.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/utsname/uname.c,v retrieving revision 1.6 diff -p -u -3 -r1.6 uname.c --- src/libc/posix/utsname/uname.c 17 Oct 2002 23:00:25 -0000 1.6 +++ src/libc/posix/utsname/uname.c 3 May 2003 12:45:01 -0000 @@ -1,3 +1,4 @@ +/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ @@ -18,6 +19,9 @@ int uname(struct utsname *u) unsigned is_486_or_better; unsigned cpuid_support; unsigned cpuid_info; + unsigned family, vendor_comp[3]; + char vendor[13]; + int i, j; if (!u) { @@ -85,21 +89,47 @@ int uname(struct utsname *u) : "%eax", "%ebx"); if (cpuid_support) { - /* Now we can use CPUID */ + /* Now we can use CPUID. CPUID is documented here: + * + * http://www.sandpile.org/ia32/cpuid.htm + */ asm volatile ( "movl $1, %%eax;" "cpuid;" - : "=a" (cpuid_info) - : - : "%ebx", "%ecx", "%edx"); - /* What we need is instruction family info in 8-11 bits */ - switch ((cpuid_info & 0x780) >> 8) - { - case 0x7: strcpy(u->machine, "i786"); break; - case 0x6: strcpy(u->machine, "i686"); break; - case 0x5: strcpy(u->machine, "i586"); break; - case 0x4: strcpy(u->machine, "i486"); break; - } + : "=a" (cpuid_info) + : + : "ebx", "ecx", "edx"); + + /* What we need is instruction family info in 8-11 bits */ + family = (cpuid_info & 0x780) >> 8; + switch (family) + { + case 0x7: strcpy(u->machine, "i786"); break; + case 0x6: strcpy(u->machine, "i686"); break; + case 0x5: strcpy(u->machine, "i586"); break; + default: + case 0x4: strcpy(u->machine, "i486"); break; + } + + /* What is the vendor name? It's returned in EBX-EDX-ECX. */ + asm volatile ( + "movl $0, %%eax;" + "cpuid;" + : "=b" (vendor_comp[0]), "=d" (vendor_comp[1]), + "=c" (vendor_comp[2]) + : + : "eax"); + + for (i = 0; i < 3; i++) { + for (j = 0; j < 4; j++) { + vendor[(i * 4) + j] = vendor_comp[i] & 0xff; + vendor_comp[i] >>= 8; + } + } + vendor[12] = '\0'; + + if ((family == 0x6) && (strcmp(vendor, "AuthenticAMD") == 0)) + strcpy(u->machine, "athlon"); } else strcpy(u->machine, "i486"); // i486 not supporting CPUID @@ -115,7 +145,7 @@ int uname(struct utsname *u) strcpy(u->nodename, "pc"); else { - int i = 8; + i = 8; dosmemget(__tb, 8, u->nodename); do { u->nodename[i--] = 0; @@ -123,3 +153,34 @@ int uname(struct utsname *u) } return 0; } + +#ifdef TEST + +#include + +int +main (int argc, char *argv[]) +{ + struct utsname u; + + if (uname(&u) < 0) + { + perror(argv[0]); + return EXIT_FAILURE; + } + + printf("machine: %s\n" + "nodename: %s\n" + "release: %s\n" + "sysname: %s\n" + "version: %s\n", + u.machine, + u.nodename, + u.release, + u.sysname, + u.version); + + return EXIT_SUCCESS; +} + +#endif /* TEST */