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