On Fri 19 Jun 2009 05:33, Li Yi pondered:
> On Fri, 2009-06-19 at 05:04 -0400, Mike Frysinger wrote:

> >  off the top of my head,
> > core Blackfin interrupt code shouldnt be triggering exceptions in the
> > first place.  if our core code paths are not causing problems, then
> > this shouldnt really be an issue.  but if our core code paths are
> > triggering exceptions, we will need to make sure that it isnt in a
> > place where we are using the disabled interrupt aspect to work around
> > anomalies (e.g. save/restore order of loop counter registers) and that
> > we dont return to that location with global interrupts enabled when
> > they arent before (i.e. we have to save/restore the IPEND[4] state).
> > and the xenomai ipipe code has to be similarly aware of these
> > anomalies.
> > 
> > the new code really should look like:
> > /* Clear IPEND[4] (global interrupt disable bit) by the special
> >  * sequence of pushing RETI onto the stack.  This way we can lower
> >  ourselves to IVG5 even if the exception was taken after the 
> >  interrupt handler was called but before it got a chance to enable
> >  global interrupts itself. 
> >  */
> > [--sp] = reti;
> > sp += 4;
> 

Normally we turn interrupts off with:

CLI Dreg ;

The Disable Interrupts instruction globally disables general interrupts by
setting IMASK to all zeros. In addition, the instruction copies the previous
contents of IMASK into a user-specified register in order to save the state of
the interrupt system.

So, sequence of:

        r6 = 0x3f;
        sti r6;

The Enable Interrupts instruction globally enables interrupts by restoring
the previous state of the interrupt system back into IMASK.

should re-enable them - even if they were turned off.

I guess a "good" test would be to try to single step (with kgdb) over an 
atomic sequence in the kernel.

How about:
release_task()
kernel/exit.c:174 <- turns off interrupts
kernel/exit.c:176 <- turns off interrupts

do_settimeofday()
kernel/time/timekeeping.c:174  <- turns off interrupts

basically - any function which does a cli...

for i in $(bfin-uclinux-objdump -d linux-2.6.x/vmlinux | grep CLI | 
awk '{print $1}' | sed 's/://' |  tr "[:lower:]" "[:upper:]"); do 
j=`echo "obase=16; ibase=16; $i - 2" | bc` ; echo -e "\n"$i; 
bfin-uclinux-addr2line -f -e ./linux-2.6.x/vmlinux $j ; done | less

_______________________________________________
Uclinux-dist-devel mailing list
Uclinux-dist-devel@blackfin.uclinux.org
https://blackfin.uclinux.org/mailman/listinfo/uclinux-dist-devel

Reply via email to