Effect of additionnal save/restore instructions

Leonard Bise leonard.bise at syderal.ch
Wed Apr 24 09:54:58 UTC 2013


Thanks a lot for your inputs guys. I realise now that I actually didn't
know exactly how to write inline assembly code properly.

Joel: Yes the goal of this function is to have a known number of cycles.
Thank you for your precious input.

Here is the final code version we settled on.

void SCET_wait_2us(void) {****

    {****

        /*#[ operation SCET_wait_2us() */****

    uint32 count;****

        /* Performs a 60us delay using an __asm__ __volatile__ loop, this
piece of code has been****

         * measured on HW to validate the duration is correct */****

    __asm__ __volatile__("set " XSTR(NB_ITER_60US) ", %0" : "=r"(count));***
*

    __asm__ __volatile__("StartLoop1us:");****

    __asm__ __volatile__("dec 1, %0" : "=r" (count));****

    __asm__ __volatile__("cmp %0, 0" : "=r" (count));****

    __asm__ __volatile__("bne StartLoop1us");****

    __asm__ __volatile__("nop");****

        /*#]*/****

    }****

}


2013/4/23 Joel Sherrill <joel.sherrill at oarcorp.com>

>  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
>
>


-- 
*
*
*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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20130424/42bdfae8/attachment.html>


More information about the users mailing list