Message-ID: <386F355D.AD5F2D14@softhome.net> Date: Sun, 02 Jan 2000 13:24:13 +0200 From: Laurynas Biveinis X-Mailer: Mozilla 4.6 [en] (Win98; I) X-Accept-Language: en MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: uname() patch - second version Content-Type: text/plain; charset=iso-8859-4 Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com The version I recovered from mail archives is buggy. It does not correctly restore EFLAGS and PUSHes to stack more than POPs, with all effects from it - strange failures and SIGSEGVs. This version corrects those bugs. Laurynas Biveinis --------------------- --- uname.c.old Sun Oct 6 00:39:50 1996 +++ uname.c Sun Jan 2 13:14:10 2000 @@ -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,81 @@ 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;" + "popl %%eax;" + "movl %%eax, %%ebx;" + "xorl $0x40000, %%eax;" + "pushl %%eax;" + "popf;" + "pushf;" + "popl %%eax;" + "cmpl %%ebx, %%eax;" + "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;