delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/11/16/20:47:56

Message-ID: <328E6D0D.168E@ananke.amu.edu.pl>
Date: Sun, 17 Nov 1996 02:40:29 +0100
From: Mark Habersack <grendel AT ananke DOT amu DOT edu DOT pl>
Reply-To: grendel AT ananke DOT amu DOT edu DOT pl
Organization: Home, sweet home
MIME-Version: 1.0
To: Morten Welinder <welinder AT rentec DOT com>
CC: "John M. Aldrich" <fighteer AT cs DOT com>,
DJGPP Workers mailing list <djgpp-workers AT delorie DOT com>
Subject: Re: djverify and cpu detection

This is a multi-part message in MIME format.

--------------4182367F18A5
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Mark Habersack wrote:

Morten Welinder wrote:
>
> 1. The asm ("...") code in diagnose.c fails to specify that
>    ebx/ecx/edx get destroyed.  Bad code may be generated.
My fault. Shall be corrected. Thanks for pointing it.

> 2. Why does it .byte and .long so often?  (And what are all
>    those '\r's doing _after_ the '\n's?)
a) The .byte and .long emit the code of the "xorl  $0xXXXX, %%eax"
instruction. The code was originally written for a 16-bit
assembler which didn't accept 32-bit instructions, so they had to be
emited manually (the same concerns CPUID in this code). I just
thoughtlessly converted the code forgetting to change the .directives to
something more readable.
b) Frankly.... I don't know why did I put the '\r's there... ;-)))

>
> 3. The method used -- as used everywhere else in djgpp --
>    may have a problem: it is said that an interrupt (the
>    event, not the handler) will clear the AC flag.
Hmm... That's correct, but the method is recommended by Intel and I
assume that they recommend a technique which is reliable enough to use
it in serious software. It's possible to disable interrupts before
flipping and checking the AC bit. If the code will run in V86 mode and
the DPMI server will virtualize the interrupt flag properly - nothing
wrong should happen.

>    If this is true then we will occasionally detect 486s
>    and up as 386s.
>
>    So someone with a PC should run the cpu detection code
>    10^8 times and see if it is reliable.  Don't forget to
>    run it in real mode as well as v86 mode.  If it turns
>    out we do have a problem we can think of a solution then.
I've been using the code for more than two years now and it detected
properly all computers ranging from 386's, through Pentium up to
PentiumPro. In fact the code was more reliable than Quarterdeck's MFT
which sometimes reported Pentium/486 to be a 386. But I think you're
right, if there are doubts they have to be dealt with.

In attachment to this mail you'll find the diff file that applies all
the changes to diagnose.c from v0.31 of DJVERIFY.

-- 
===========================================================
October. And the trees are stripped bare of all they wear.
What do I care? October.
And Kingdoms rise, And Kingdoms fall,
But you go on, and on.
===========================================================

--------------4182367F18A5
Content-Type: text/plain; charset=us-ascii; name="diagnose.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="diagnose.diff"

*** diagnose.org	Fri Nov 15 23:39:20 1996
--- diagnose.c	Sun Nov 17 02:28:28 1996
***************
*** 71,77 ****
  void   analyze_environment	( void );
  void   find_djgpp_file		( char **s, const char *filename );
  
! unsigned getCPU			( void );
  static void usec_sleep          ( int usec );
  static unsigned char read_cmos  ( int reg );
  int    installed_memory_size    ( void );
--- 71,77 ----
  void   analyze_environment      ( void );
  void   find_djgpp_file          ( char **s, const char *filename );
  
! volatile unsigned getCPU                 ( void );
  static void usec_sleep          ( int usec );
  static unsigned char read_cmos  ( int reg );
  int    installed_memory_size    ( void );
***************
*** 672,728 ****
  /*       architecture, not yet available) I read about.         */
  /****************************************************************/
  
! unsigned getCPU( void )
  {
!    unsigned short     wcpu;
  
!    asm ("movl    %%esp, %%ebx\n\r"
!         "andl    $0xFFFFFFFC, %%esp\n\r" /* This aligns stack to avoid AC fault */
!         "pushfl\n\r"
!         "popl    %%eax\n\r"
!         "movl    %%eax, %%ecx\n\r"
!         ".byte   0x35\n\r"
!         ".long   0x40000\n\r"
!         "pushl   %%eax\n\r"
!         "popfl\n\r"
!         "pushfl\n\r"
!         "popl    %%eax\n\r"
!         "xorl    %%ecx, %%eax\n\r"
!         "movw    $2, %0\n\r" /* It's 80386 - cannot flip the AC bit in EFLAGS */
!         "movl    %%ebx, %%esp\n\r"
!         "jz      1f\n\r"
!         "andl    $0xFFFFFFFC, %%esp\n\r" /* This aligns stack to avoid AC fault */
!         "pushl   %%ecx\n\r"
!         "popfl\n\r"
!         "movl    %%ebx, %%esp\n\r"
!         "movl    $3, %0\n\r"	    /* Assume it's i486 */
!         "movl    %%ecx, %%eax\n\r"
!         ".byte   0x35\n\r"
!         ".long   0x200000\n\r"
!         "pushl   %%eax\n\r"
!         "popfl\n\r"
!         "pushfl\n\r"
!         "popl    %%eax\n\r"
!         "xorl    %%ecx, %%eax\n\r"
!         "je              1f\n\r"    /* If can toggle ID bit in EFLAGS - it's */
!         "movw    $4, %0\n\r"	    /* "new" i486 code */
!         "xorl    %%eax, %%eax\n\r"  /* "new" i486 with CPUID instruction */
!         ".byte   0x0F\n\r"          /* or Pentium and higher */
!         ".byte   0xA2\n\r"          /* Issue CPUID instruction code */
!         "cmpl    $1, %%eax\n\r"     /* See whether 1 is supported with CPUID */
!         "jl              1f\n\r"    /* No. So let's report we have "new" i486 */
!         "xorl    %%eax, %%eax\n\r"
!         "incl    %%eax\n\r"
!         ".byte   0x0F\n\r"
!         ".byte   0xA2\n\r"          /* CPUID again */
!         "andl    $0x0F00, %%eax\n\r"
!         "shrl    $8, %%eax\n\r"
!         "xorb    %%ah, %%ah\n\r"
!         "movw    %%ax, %0\n\r"
!         "1:"
          : "g=" (wcpu)
          :
!         : "%eax");
  
     return (unsigned)wcpu;
  }
--- 672,732 ----
  /*       architecture, not yet available) I read about.         */
  /****************************************************************/
  
! volatile unsigned getCPU( void )
  {
!    volatile unsigned short     wcpu;
  
!    /* The code below tries to disable interrupts to be sure that no bit
!       in eflags register will be modified by interrupt event/handler.
!       Thanks to Morten for pointing that problem.
!    */
!    asm volatile ("cli\n"
!         "movl    %%esp, %%ebx\n"
!         "andl    $0xFFFFFFFC, %%esp\n" /* This aligns stack to avoid AC fault */
!         "pushfl\n"
!         "popl    %%eax\n"
!         "movl    %%eax, %%ecx\n"
!         "xorl    $0x40000, %%eax\n"
!         "pushl   %%eax\n"
!         "popfl\n"
!         "pushfl\n"
!         "popl    %%eax\n"
!         "xorl    %%ecx, %%eax\n"
!         "movw    $2, %0\n" /* It's 80386 - cannot flip the AC bit in EFLAGS */
!         "movl    %%ebx, %%esp\n"
!         "jz      1f\n"
!         "andl    $0xFFFFFFFC, %%esp\n" /* This aligns stack to avoid AC fault */
!         "pushl   %%ecx\n"
!         "popfl\n"
!         "movl    %%ebx, %%esp\n"
!         "movl    $3, %0\n"        /* Assume it's i486 */
!         "movl    %%ecx, %%eax\n"
!         "xorl    $0x200000, %%eax\n"
!         "pushl   %%eax\n"
!         "popfl\n"
!         "pushfl\n"
!         "popl    %%eax\n"
!         "xorl    %%ecx, %%eax\n"
!         "je              1f\n"    /* If can toggle ID bit in EFLAGS - it's */
!         "movw    $4, %0\n"        /* "new" i486 code */
!         "xorl    %%eax, %%eax\n"  /* "new" i486 with CPUID instruction */
!         ".byte   0x0F\n"          /* or Pentium and higher */
!         ".byte   0xA2\n"          /* Issue CPUID instruction code */
!         "cmpl    $1, %%eax\n"     /* See whether 1 is supported with CPUID */
!         "jl              1f\n"    /* No. So let's report we have "new" i486 */
!         "xorl    %%eax, %%eax\n"
!         "incl    %%eax\n"
!         ".byte   0x0F\n"
!         ".byte   0xA2\n"          /* CPUID again */
!         "andl    $0x0F00, %%eax\n"
!         "shrl    $8, %%eax\n"
!         "xorb    %%ah, %%ah\n"
!         "movw    %%ax, %0\n"
!         "1:\n"
!         "sti\n"
          : "g=" (wcpu)
          :
!         : "%eax", "%ebx", "%ecx", "%edx");
  
     return (unsigned)wcpu;
  }

--------------4182367F18A5--


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019