Mail Archives: djgpp-workers/1999/08/04/13:39:26
Eli Zaretskii wrote:
> Could you please modify the library function `uname' to include this
> code, and send the results of "diff -c" against the current source?
OK. Code was in program for testing purposes, if you consider that
it is production quality - here is diff against CVS version of
library. It compiled and worked for me. Also there is a patch for
docs which describes the new behaviour and corrects a typo ("#" char
before function prototype).
BTW, I made "diff -u" not "diff -c", but I think you will accept that? :)
Bye,
Laurynas Biveinis
-----------------
diff -r -u utsname.old/uname.c utsname/uname.c
--- utsname.old/uname.c Sat Oct 5 23:39:50 1996
+++ utsname/uname.c Wed Aug 4 17:35:24 1999
@@ -13,6 +13,9 @@
{
__dpmi_regs r;
unsigned short dos_version;
+ unsigned is_486_or_better;
+ unsigned cpuid_support;
+ unsigned cpuid_info;
if (!u)
{
@@ -25,7 +28,80 @@
u->sysname[sizeof(u->sysname) - 1] = '\0';
sprintf(u->release, "%d", dos_version >> 8);
sprintf(u->version, "%02d", dos_version & 0xff);
- strcpy(u->machine, "pc");
+
+ /* CPU detection code by Laurynas Biveinis */
+ /* Uses Phil Frisbie, Jr 386 and CPUID detection code */
+
+ /* Let's check for 386. Intel says that 386 is unable to set or clear */
+ /* value of 18 bit in EFLAGS (AC). So we toggle this bit and see if */
+ /* we succeed */
+ asm volatile (
+ "pushf;" /* save EFLAGS */
+ "movl %%eax, %%ebx;" /* temp storage EFLAGS */
+ "xorl $0x40000, %%eax;" /* change AC bit in EFLAGS */
+ "pushl %%eax;" /* put new EFLAGS value on stack */
+ "popf;" /* replace current EFLAGS value */
+ "pushf;" /* get EFLAGS */
+ "popl %%eax;" /* save new EFLAGS in EAX */
+ "cmpl %%ebx, %%eax;" /* compare temp and new EFLAGS */
+ "jz 0f;"
+ "movl $1, %0;" /* 80486+ present */
+ "jmp 1f;"
+ "0:"
+ "movl $0, %0;" /* 80386 present */
+ "1:"
+ "pushl %%ebx;" /* get original EFLAGS */
+ "popf;" /* restore EFLAGS */
+ : "=g" (is_486_or_better)
+ :
+ : "eax", "ebx");
+ if (is_486_or_better)
+ {
+ /* In the same way we checked for 386, we will check for CPUID now, */
+ /* using 21 bit in EFLAGS (ID bit) */
+ asm volatile (
+ "pushf;" /* get extended flags */
+ "popl %%eax;"
+ "movl %%eax, %%ebx;" /* save current flags */
+ "xorl $0x200000, %%eax;" /* toggle bit 21 */
+ "pushl %%eax;" /* put new flags on stack */
+ "popfl;" /* flags updated now in flags */
+ "pushfl;" /* get extended flags */
+ "popl %%eax;"
+ "xorl %%ebx, %%eax;" /* if bit 21 r/w then supports cpuid */
+ "jz 0f;"
+ "movl $1, %0;"
+ "jmp 1f;"
+ "0:"
+ "movl $0, %0;"
+ "1:"
+ "pushl %%ebx;" /* Restore */
+ "popfl;" /* original EFLAGS */
+ : "=g" (cpuid_support)
+ :
+ : "%eax", "%ebx");
+ if (cpuid_support)
+ {
+ /* Now we can use CPUID */
+ 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 0x6: strcpy(u->machine, "i686"); break;
+ case 0x5: strcpy(u->machine, "i586"); break;
+ case 0x4: strcpy(u->machine, "i486"); break;
+ }
+ }
+ else
+ strcpy(u->machine, "i486"); // i486 not supporting CPUID
+ }
+ else
+ strcpy(u->machine, "i386");
r.x.ax = 0x5e00;
r.x.ds = __tb >> 4;
diff -r -u utsname.old/uname.txh utsname/uname.txh
--- utsname.old/uname.txh Sun Sep 27 17:22:28 1998
+++ utsname/uname.txh Wed Aug 4 17:43:36 1999
@@ -4,7 +4,7 @@
@example
#include <sys/utsname.h>
-#int uname(struct utsname *u);
+int uname(struct utsname *u);
@end example
@subheading Description
@@ -25,7 +25,7 @@
@item machine
-"pc"
+The CPU family type: "i386", "i486", "i586" or "i686".
@item nodename
- Raw text -