Effect of additionnal save/restore instructions

Joel Sherrill joel.sherrill at OARcorp.com
Tue Apr 23 15:09:03 UTC 2013


Hi

SPARC register usage combined with the the register windowing
makes things difficult to figure out.  Using save/restore in the middle
of inline assembly like that is too scary for my personal taste. It is
certainly not normal SPARC programming.

I don't like the fact they used a "trivial" save instruction which adds
0 bytes to the stack as best I can tell. It is equivalent to
"save %g0,%g0,%g0". Normal usage includes three real arguments
and looks more like this:

         PUBLIC(_CPU_Context_save_fp)
SYM(_CPU_Context_save_fp):
         save    %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp

That saves space on the stack to save the window. I THINK the trivial
save rotates the CWP but doesn't make space. I expect this would
lead to a crash eventually as (my guess) is that you end up with
two register windows associated with the same spot on the stack.
You have rotated twice but only saved one hole on the stack. As
you start returning and restoring, I expect this would result in
some odd type of stack reuse.

My first question is always ... Why is this in inline assembly anyway?

If it is to do a tight loop with a known number of cycles, then the
second round of questions are:

+ Why didn't they use the proper asm statement constraints?
+ Why isn't this asm volatile?
+ What happens if an interrupt occurs in the middle of this?

If you are using a general purpose register gcc may use, then you need to
specify that. Generally speaking, you can declare local variables and "pass"
them to inline asm via constraint specifications. This lets gcc pick the 
register(s)
and avoids one type of trouble.

There are some asm with constraint examples in cpukit/score/cpu/sparc.

--joel

On 4/23/2013 4:02 AM, Leonard Bise wrote:
> Hello all,
>
> I'm having a problem regarding the processor window registers that I 
> cannot explain easily mostly because I'm not super familiar with this 
> subject.
>
> First, I'm using a LEON2 Sparc v8 processor and RTEMS 4.8 version 
> which is required by our project.
>
> We have a function using inline assembly to perform a flat delay, here 
> is the code it use.
>
> void SCET_wait_2us(void) {
>
>     {
>
>   /*#[ operation SCET_wait_2us() */
>
>   /* Performs a 60us delay using an ASM loop, this piece of code has been
>
>    * measured on HW to validate the duration is correct */
>
>   __asm__("                \
>
> save;                  \
>
>           set " XSTR(NB_ITER_60US) ", %l7; \
>
>           StartLoop1us:            \
>
>           dec 1, %l7;              \
>
>           cmp %l7, 0;              \
>
>           bne StartLoop1us;          \
>
>           nop;                   \
>
> restore;               \
>
>           ");
>
>   /*#]*/
>
>     }
>
> }
>
>
> Originally this code didn't have the save and restore instruction but 
> our sub contractor added them because they had problems compiling. I 
> find it an odd solution but whatever.
>
> Once this code was implemented we started seeing random processor 
> reset occurring in various contexts.
>
> I tested this code while being in the Eclipse debugger and once the 
> crash happened I noticed I had a segmentation fault in Eclipse. I used 
> GRMON to check the processor register and noticed that the last trap 
> that occurred was a window underflow trap 0x06.
>
> I found in the RTEMS sources the code for this handler, and while I 
> haven't understood everything I took out that the code was trying to 
> recover from this error, is this correct?
> I copied the trap handler code below.
>
> RTEMS 4.8 branch
> file : rtems / c / src / lib / libcpu / sparc / reg_win / window.S
> *
> *
> SYM(window_underflow_trap_handler):
>
>         /*
>          * Calculate new WIM by "rotating" the valid bits in the WIM left
>          * by one position. The following shows how the bits move for 
> a SPARC
>          * cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8.
>          *
>          * OLD WIM = 76543210
>          * NEW WIM = 07654321
>          *
>          * NOTE: New WIM must be stored in a global register since the
>          * "save" instruction just prior to the load of the wim
>          * register will result in the local register set changing.
>          */
>
>         mov %wim, %l3 ! Calculate new WIM
>         sll %l3, 1, %l4 ! l4 = WIM << 1
>         srl %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5
>                                         ! l5 = WIM >> (Number Windows-1)
>         or %l5, %l4, %l5 ! l5 = (WIM << 1) |
>                                         ! (WIM >> (Number Windows-1))
>         mov %l5, %wim ! load the new WIM
>         nop; nop; nop
>         restore ! Two restores to get into the
>         restore ! window to restore
>         ldd [%sp + 0x00], %l0 ! First the local register set
>         ldd [%sp + 0x08], %l2
>         ldd [%sp + 0x10], %l4
>         ldd [%sp + 0x18], %l6
>         ldd [%sp + 0x20], %i0 ! Then the input registers
>         ldd [%sp + 0x28], %i2
>         ldd [%sp + 0x30], %i4
>         ldd [%sp + 0x38], %i6
>         save ! Get back to the trap window.
>         save
>         jmp %l1 ! Re-execute restore.
>         rett %l2
>
> From my understanding this code should not ever fail, is that correct?
> What I'm not sure is that if this type of trap can be a 
> common occurrence or if that means something went bad in the software.
>
> Basically now I removed the save/restore and it seems to be working 
> fine but I'll have to explain exactly what was happening before.
> Is the compiler not expecting the user to add save/restore and could 
> that lead to the behavior we see sometimes (processor reset). What are 
> the usual way to handle this type of inline assembly? Never use 
> save/restore?
>
> Also our customer gave us a sequence of command to send to the 
> software that would produce this reset systematically however when we 
> got the equipment over here, I tried with the same code the sequence 
> and it is not happening as often as they say. There seem to be a lot 
> of randomness to this problem.
>
> I really hope someone can provide some knowledge on this type of issue.
> -- 
> *
> *
> *Léonard Bise*
> Software Design Engineer
> Direct Line +41 (0)32 338 9902
>
> *SYDERAL SA*
> Neuenburgstrasse 7
> CH-3238 Gals (Switzerland)
> Desk Line +41 (0)32 338 9800
> Web Site http://www.syderal.ch


-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20130423/39f7dd32/attachment.html>


More information about the users mailing list