This is the mail archive of the ecos-discuss@sourceware.cygnus.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: eCos FP support suggestions.


Sergei Organov <osv@Javad.RU> writes:

> Hello,
> 
> Here are my thoughts about floating point support implementation for
> eCos. Your objections, comments and suggestions are welcome.
> 
> Support for three different configurations of FP context handling are
> required:
> 
> 1. All tasks are floating point.
> 2. Some tasks are floating point, immediate FP context switch.
> 3. Some tasks are floating point, lazy (deferred) FP context switch.
> 

[Details snipped]


Sergei,

I have finally got around to taking a look at this, I've been busy on
more urgent things for the last week or so.

Your scheme does not correspond to the way in which I intended to
implement FP handling. In particular, I want to keep the FP stuff
entirely in the HAL and not make any changes to the kernel or HAL APIs
at all, which I do not believe are necessary. We also have to make
sure that the right things happen during interrupt and exception
handling and for debugging.

The options for FP support that I want to see are:

1. All threads are FP, with full save/restore on context switch.

2. Threads are non-FP until first use, then they do a full
   save/restore each context switch.

3. Threads are non-FP until first use, then the FP context is
   saved/restored lazily as necessary.

I think these correspond to yours options.

For all options we need to extend the HAL_SavedRegisters structure to
contain the FP state. Although for option 3 this may consist of
a pointer to a second structure allocated elsewhere on the stack.

Option 1 is easily implemented by adding code to the context switch,
interrupt and exception state save/restore code. This has already been
implemented in the MIPS HAL.

Option 2 requires an extra flag to be added to the HAL_SavedRegisters
structure to indicate whether the thread has a valid FP state. This is
set false on initialization and the FPU disabled whenever the thread
is switched to. If the thread performs an FP operation the FP
exception handler sets the flag true and the FPU is initialized.
Subsequently, when the thread is switched out, the flag is checked and
the FPU context saved. Similarly the FPU context will be restored when
the thread is reloaded. Optimizations can be added to this to allow
the HAL to avoid allocating the FPU save area if the thread does not
do FP operations.

Option 3 presents something of a problem. Notionally it is a
development of option 2 where the actual FPU state swap is handled in
the FP exception handler only if necessary. However, here's the
problem: by the time we have decided to load the FPU state from the
current thread, we will have destroyed it, since it is simply stored
on the stack as part of the CPU state we have already loaded.

A solution to this is to allocate a per-thread "static" FP save area
at the base of the stack, since it must persist after the rest of the
thread's CPU state is loaded. However, this would prevent us using FP
in exception or interrupt routines: an unreasonable and unenforceable
restriction (although we could make that a configuration option if the
user is prepared to exert the correct level of self-restraint).

A development of this idea, and probably the right way to do it, is to
have an initial "static" save area that is used during normal thread
switching, and to allocate a new FPU save area during exception and
interrupt handling. These are then chained together and pointed to by
a field in the HAL_SavedRegisters, which is used to maintain a HAL
level pointer to the current thread's FPU save area. An additional
pointer will then point to the save area for the current FPU contents
owner. A thread context switch involves disabling the FPU, saving the
current thread's FPU context pointer into the CPU save state and
loading the pointer from the next thread. If the new thread performs
an FPU operation, the exception handler saves the FPU context to the
save area pointed to by the FPU owner pointer, loads the FPU context
from the current thread's context pointer and copies it to the FPU
context owner pointer. Exceptions and interrupts must also disable the
FPU, and in addition will create a new FPU save area which replaces
the current thread's save area pointer. Any FP operations will then
cause a fresh FPU context to be created, rather than use the current
thread's existing context. Exception or interrupt return will just
cause the new context to be destroyed and the original current
thread's pointer to be restored.

The only addition we will need to the HAL API will be a new macro,
HAL_CPU_FLUSH_CONTEXT() or something similar, to force the FPU
contents out to the save area for the benefit of debugging.

I intend to experimentally implement these mechanisms in the MIPS HAL,
to check that it all works properly, although I don't know exactly
when I will find the time to do this. In the meantime I suggest that
you try implementing Option 1 only, which will allow you to at least
use the FPU, although at slightly reduced performance. Once I am happy
that I have not missed any subtleties in the MIPS HAL, you can then
use that as a model to implement the PowerPC version. That way we will
hopefully get a uniform implementation across all HALs.


Suggestions, criticism and comments are of course welcome.

-- 
Nick Garnett           mailto:nickg@cygnus.co.uk
Cygnus Solutions, UK   http://www.cygnus.co.uk

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]