Message-ID: <37A8643F.CCFFBD9A@softhome.net> Date: Wed, 04 Aug 1999 18:03:11 +0200 From: Laurynas Biveinis X-Mailer: Mozilla 4.61 [en] (Win98; I) X-Accept-Language: lt,en MIME-Version: 1.0 To: Eli Zaretskii CC: DJGPP Workers Subject: Re: CPU ID program, second version References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com 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 -#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