Basham, Richard R wrote:
> 
> Jan, Garth,
> 
> That is a very good point.  I don't know of a work around for using rt_task_use_fp 
>and interrupts other than what you are already doing.  If Garth is using or expecting 
>to use floating point he may have to keep his code the way it is.  Maybe, someone 
>else in this group can enlighten us further on using floating point within interrupt 
>service routines.
> 

Hi, below you'll find an answer I sent to many people.

Here is what I do when I've to do what you are doing, a lot of do(s),
eh!

unsigned long my_fpu_reg[27];
unsigned long linux_fpu_reg[27]; 
unsigned long linux_cr0; 


        __asm__ __volatile__("movl %%cr0,%%eax; clts": "=a" (linux_cr0):
:
"ax");
        __asm__ __volatile__("fnsave %0" : "=m" (linux_fpu_reg));
        __asm__ __volatile__("frstor %0" : "=m" (my_fpu_reg));

// FLOATING POINT CALCs HERE

        __asm__ __volatile__("fnsave %0" : "=m" (my_fpu_reg));
        __asm__ __volatile__("frstor %0" : "=m" (linux_fpu_reg));
        __asm__ __volatile__("movl %%eax,%%cr0": :"a" (linux_cr0):
"ax");

Just not to have it blindly.
The most important thing is the "clts" instruction. Save restore of
Linux fpu are required only if Linux uses the fpu, "clts" always, as it
is always
set whenever Linux switches processes (TS means task switched flag). If
TS is set any fp operation causes a trap 7 to "device not available"
until it is cleared. Linux understands from it that the new running
process uses the fpu and must set it up appropriately. Register cr0 must
be saved/restored otherwise your "clts" can hide to Linux that a process
just switched to, but interrupted by you before Linux clts it, uses the
fpu. "fnsave" clears the fpu so no finit is needed after an fnsave. 
Roughly, I can remember that the couple fnsave/frstor is about 1 us on a
233 Mhz PII, 200 cycles at most. Save restore of cr0 is about 20/30
cycles. So the above is about 2 us.
Recall again that while keeping "clts" you can avoid saving/restoring
Linux fpu if no Linux foreground process does not use it. Moreover 
there is often no need to restore/save your fpu registers in the
interrupt
handler if each time you complete your calculation and do not leave
anything pending in the fpu, which is likely always the case. In such
cases you are enough doing:

        __asm__ __volatile__("movl %%cr0,%%eax; clts": "=a" (linux_cr0):
:
"ax");
        __asm__ __volatile__("fnsave %0" : "=m" (linux_fpu_reg));

// FLOATING POINT CALCs HERE

        __asm__ __volatile__("frstor %0" : "=m" (linux_fpu_reg));
        __asm__ __volatile__("movl %%eax,%%cr0": :"a" (linux_cr0):
"ax");

if Linux uses the fpu, or simply

        __asm__ __volatile__("movl %%cr0,%%eax; clts": "=a" (linux_cr0):
:
"ax");

 // FLOATING POINT CALCs HERE

        __asm__ __volatile__("movl %%eax,%%cr0": :"a" (linux_cr0):
"ax");

if Linux does not.

I'll hope there are no typos in the above and I'm glad to help you in a
matter that costed me a lot of "blood shedding" just to discover, once
solved, that was that simple. Daniele Lugli was fundamental in pointing
out such a crucial problem to the newsgroups and in working with me to
solve it.


Ciao, Paolo.
--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/

Reply via email to