Message-ID: <37A800B1.D4B0B30C@softhome.net> Date: Wed, 04 Aug 1999 10:58:25 +0200 From: Laurynas Biveinis X-Mailer: Mozilla 4.61 [en] (Win98; I) X-Accept-Language: lt,en MIME-Version: 1.0 To: DJGPP Workers Subject: CPU ID program, second version Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Hello, if all what "uname -m" has to do is print i[3-6]86, then this program below should do it correctly. I went to AMD and Cyrix web sites, fetched docs and added support for these CPU, but is it necesarry at all? If no - prg below should do the trick. If yes - there is extended version which detects CPU vendor. Just tell me. So the main difference from previous prg is removed check for "GenuineIntel" and generic check for CPU instruction family with CPUID is used instead. Laurynas Biveinis ----------------- /* CPU type under DJGPP checker, v1.1alpha */ /* (C) 1999 Laurynas Biveinis */ /* Uses CPU detection routines by Phil Frisbie */ #include int main(void) { unsigned is_486_or_better; unsigned supports_cpuid; unsigned vendor_id[3]; unsigned version_info; /* 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 */ "popl %%eax;" /* get 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 486 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:" : "=g" (supports_cpuid) : : "%eax", "%ebx"); if (supports_cpuid) { /* Now we can use CPUID */ asm volatile ( "movl $1, %%eax;" "cpuid;" : "=a" (version_info) : : "%ebx", "%ecx", "%edx"); /* What we need is family info in 8-11 bits */ version_info = (version_info & 0x780) >> 8; switch (version_info) { case 0x6: printf("i686\n"); break; case 0x5: printf("i586\n"); break; case 0x4: printf("i486\n"); break; } } else printf("i486\n"); } else printf("i386\n"); return 0; }