[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pc386 on 386sx



joel at OARcorp.com wrote:

> On Wed, 28 Jul 1999, erik.ivanenko wrote:
>
> > I have problems with two boards that do not have co-processors.  One
> > board is an ACER PIA-632 with an ALI chipset -- a 386sx "clone", the
> > other a PC clone with an Intel 486sx.   In both cases, they fail during
> > CPU_initialize, in cpu.c.
> >
> > Even though the no-wait form of the math co-processor init instruction
> > is used ( fninit ), "Exception 7"  is generated, gets trapped by the
> > exception management code, and prints the screen dump.  This happens in
> > an infinite loop.  (  Pictures of the screen were taken with a digital
> > camera to get that info.  At the point of failure,  ax contains 0xa5a5,
> > which is what fp_status is set to prior to the fninit and fnstsw
> > instructions.  )
>
> I think I replied to someone at some time about this but here goes again.
> :)
>
> The assumption behind fninit being used there is based on the circa 1986
> version of the original 80386 manual (before it was even a DX).  It is
> quite likely given the haphazard way in which the x86 architecture has
> evolved, that the assumption made that fninit (no-wait version) would be
> safe to use when there was not a coprocessor is a bogus one.

> My gut hunch is that (1) this code should be optionally disabled when
> on a CPU model which has only software FP (i386ex for example).  (2) if HW
> floating point is optional for the CPU model, then the executive must base
> its action on a dynamic check of the cpu model.
>
> > After fninit and fnstsw instructions were commented out,  hello world,
> > ticker and cdtest now all work.
> >
> > Note that the test in cpuModel.S did not have to be commented out.
>
> > Why should this instruction fail in CPU_Initialize for these cpu's?  It
> > is fine for the i386ex.  In all cases, the RTEMS_CPU_MODEL is i386_nofp.
>
> Bad assumption based on the original 80386 documentation.  There is no
> architectural consistency on this matter because there is no real
> architectural behavior specification independent on CPU model
> implementations.
>
> I think the patch below my signature is a simple fix.  The assumption was
> that these instructions could be executed when the FP was not there.  The
> simplest thing is to disable this path.  My patch does that.
>
> > Can this be fixed so that the code can be uncommented? I don't want to
> > be that out of step with the distribution.
>
> I think so.
>
> The more general solution is to use the cpuModel-like code to determine if
> the CPU model can support an FPU and use that in ADDITION to the patch I
> am posting to disable all FP actions on the fly if the FPU is not there.
>
> This does again raise the question about the boundary between libcpu and
> score/cpu.  if the executive needs to know this information, then the
> cpuModel code is crossing the boundary. :)
>
> --joel
> Joel Sherrill, Ph.D.             Director of Research & Development
> joel at OARcorp.com                 On-Line Applications Research
> Ask me about RTEMS: a free RTOS  Huntsville AL 35805
>    Support Available             (256) 722-9985
>
> Index: cpu.c
> ===================================================================
> RCS file: /usr1/rtems/CVS-PRIVATE/rtems/c/src/exec/score/cpu/i386/cpu.c,v
> retrieving revision 1.22
> diff -c -r1.22 cpu.c
> *** cpu.c       1999/05/28 16:08:18     1.22
> --- cpu.c       1999/07/29 15:26:24
> ***************
> *** 47,57 ****
>      *  Manual and should work on any coprocessor greater than
>      *  the i80287.
>      *
> !    *  NOTE: The NO RTEMS_WAIT form of the coprocessor instructions
>      *        MUST be used in case there is not a coprocessor
>      *        to wait for.
>      */
>
>     fp_status = 0xa5a5;
>     asm volatile( "fninit" );
>     asm volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) );
> --- 47,58 ----
>      *  Manual and should work on any coprocessor greater than
>      *  the i80287.
>      *
> !    *  NOTE: The NO WAIT form of the coprocessor instructions
>      *        MUST be used in case there is not a coprocessor
>      *        to wait for.
>      */
>
> + #if CPU_HARDWARE_FP
>     fp_status = 0xa5a5;
>     asm volatile( "fninit" );
>     asm volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) );
> ***************
> *** 64,69 ****
> --- 65,72 ----
>                                  : "0"  (fp_context)
>                   );
>     }
> + #endif
> +
>   }
>
>   /*PAGE

  I have a different solution.  There is an external variable hard_math set
in cpuModel.S that is available in cpu.c -- in fact cpuModel.h is included in
cpu.c.

I've successfully tested using " if ( hard_math) { " in place of the #define
CPU_HARDWARE_FP, and a closing brace in place of the #endif.  Yes, this means
the boundary is crossed.  If you want to avoid that, the state of the
hard_math variable mirrors the EM bit of CR0.  That can be checked instead,
which decouples the two files in that regard.  ( It was just easier for me to
test hard_math. )

Also:

ALL fp instructions will raise exception 7 when the EM bit is set in CR0.
This is why the second fnint crashes the sx machines.  The EM bit is set in
cpuModel.c.  So currently, the code believes a FP emulator is hooked to
exception 7.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: vcard.vcf
Type: text/x-vcard
Size: 291 bytes
Desc: Card for Erik Ivanenko
Url : http://rtems.rtems.org/pipermail/rtems-users/attachments/19990729/b1ff2d04/attachment.vcf