[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
pc386 on 386sx
- Date: Thu, 29 Jul 1999 10:15:08 -0700
- From: erik.ivanenko at utoronto.ca (erik.ivanenko)
- Subject: 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