<div dir="ltr">Thanks a lot for your inputs guys. I realise now that I actually didn't know exactly how to write inline assembly code properly.<div><br></div><div>Joel: Yes the goal of this function is to have a known number of cycles. Thank you for your precious input.<br>
<div><br></div><div>Here is the final code version we settled on.</div><div><br></div><div><p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">void SCET_wait_2us(void) {<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    {<u></u><u></u></span></p><p class="" style="font-family:arial,sans-serif;font-size:13px">
<span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        /*#[ operation SCET_wait_2us() */<u></u><u></u></span></p><p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    uint32 count;<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        /* Performs a 60us delay using an __asm__ __volatile__ loop, this piece of code has been<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">         * measured on HW to validate the duration is correct */<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("set " XSTR(NB_ITER_60US) ", %0" : "=r"(count));<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("StartLoop1us:");<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("dec 1, %0" : "=r" (count));<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("cmp %0, 0" : "=r" (count));<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("bne StartLoop1us");<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("nop");<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        </span><span lang="FR-BE" style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">/*#]*/<u></u><u></u></span></p>
<p class="" style="font-family:arial,sans-serif;font-size:13px"><span lang="FR-BE" style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    }<u></u><u></u></span></p><p class="" style="font-family:arial,sans-serif;font-size:13px">
<span lang="FR-BE" style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">}</span></p></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/23 Joel Sherrill <span dir="ltr"><<a href="mailto:joel.sherrill@oarcorp.com" target="_blank">joel.sherrill@oarcorp.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <div>Hi<br>
      <br>
      SPARC register usage combined with the the register windowing<br>
      makes things difficult to figure out.  Using save/restore in the
      middle<br>
      of inline assembly like that is too scary for my personal taste.
      It is<br>
      certainly not normal SPARC programming.<br>
      <br>
      I don't like the fact they used a "trivial" save instruction which
      adds<br>
      0 bytes to the stack as best I can tell. It is equivalent to <br>
      "save %g0,%g0,%g0". Normal usage includes three real arguments<br>
      and looks more like this:<br>
      <br>
              PUBLIC(_CPU_Context_save_fp)<br>
      SYM(_CPU_Context_save_fp):<br>
              save    %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp<br>
      <br>
      That saves space on the stack to save the window. I THINK the
      trivial<br>
      save rotates the CWP but doesn't make space. I expect this would <br>
      lead to a crash eventually as (my guess) is that you end up with<br>
      two register windows associated with the same spot on the stack.<br>
      You have rotated twice but only saved one hole on the stack. As<br>
      you start returning and restoring, I expect this would result in<br>
      some odd type of stack reuse.<br>
      <br>
      My first question is always ... Why is this in inline assembly
      anyway?<br>
      <br>
      If it is to do a tight loop with a known number of cycles, then
      the<br>
      second round of questions are: <br>
      <br>
      + Why didn't they use the proper asm statement constraints?<br>
      + Why isn't this asm volatile?<br>
      + What happens if an interrupt occurs in the middle of this?<br>
      <br>
      If you are using a general purpose register gcc may use, then you
      need to<br>
      specify that. Generally speaking, you can declare local variables
      and "pass"<br>
      them to inline asm via constraint specifications. This lets gcc
      pick the register(s)<br>
      and avoids one type of trouble.<br>
      <br>
      There are some asm with constraint examples in
      cpukit/score/cpu/sparc.<br>
      <br>
      --joel<div><div class="h5"><br>
      <br>
      On 4/23/2013 4:02 AM, Leonard Bise wrote:<br>
    </div></div></div><div><div class="h5">
    <blockquote type="cite">
      <div dir="ltr">Hello all,
        <div><br>
        </div>
        <div>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.</div>
        <div><br>
        </div>
        <div>
          First, I'm using a LEON2 Sparc v8 processor and RTEMS 4.8
          version which is required by our project.</div>
        <div><br>
        </div>
        <div>We have a function using inline assembly to perform a flat
          delay, here is the code it use.</div>
        <div><br>
        </div>
        <div>
          <div style="border:1pt solid windowtext;padding:1pt 4pt">
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">void
                SCET_wait_2us(void)
                {</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">    {</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /*#[ operation SCET_wait_2us() */</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /* Performs a 60us delay using an ASM loop, this piece
                of code has been</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                   * measured on HW to validate the duration is correct
                */</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  __asm__("                
                               \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          </span><span>save;          
                                 \</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          set " XSTR(NB_ITER_60US) ", %l7; \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          StartLoop1us:        
                           \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          dec 1, %l7;        
                             \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          cmp %l7, 0;        
                             \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          bne StartLoop1us;      
                         \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          nop;          
                                  \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          </span><span>restore;          
                              \</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          ");</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /*#]*/</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">    }</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">}</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
          </div>
          <div><br>
          </div>
          <div>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.</div>
          <div>
            <br>
          </div>
          <div>Once this code was implemented we started seeing
            random processor reset occurring in various contexts.</div>
          <div><br>
          </div>
          <div>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.</div>
          <div><br>
          </div>
          <div>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?</div>
          <div>
            I copied the trap handler code below.</div>
          <div><br>
          </div>
          <div>RTEMS 4.8 branch</div>
          file : rtems / c / src / lib / libcpu / sparc / reg_win /
          window.S
          <div><strong style="line-height:25px;font-size:18px;font-family:Helvetica,arial,freesans,clean,sans-serif;margin:0px;border:0px;padding:0px"><br>
            </strong></div>
          SYM(window_underflow_trap_handler):<br>
          <br>
                  /*<br>
                   * Calculate new WIM by "rotating" the valid bits in
          the WIM left<br>
                   * by one position. The following shows how the bits
          move for a SPARC<br>
                   * cpu implementation where
          SPARC_NUMBER_OF_REGISTER_WINDOWS is 8.<br>
                   *<br>
                   * OLD WIM = 76543210<br>
                   * NEW WIM = 07654321<br>
                   *<br>
                   * NOTE: New WIM must be stored in a global register
          since the<br>
                   * "save" instruction just prior to the load of the
          wim<br>
                   * register will result in the local register set
          changing.<br>
                   */<br>
          <br>
                  mov %wim, %l3 ! Calculate new WIM<br>
                  sll %l3, 1, %l4 ! l4 = WIM << 1<br>
                  srl %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5<br>
                                                  ! l5 = WIM >>
          (Number Windows-1)<br>
                  or %l5, %l4, %l5 ! l5 = (WIM << 1) |<br>
                                                  ! (WIM >>
          (Number Windows-1))<br>
                  mov %l5, %wim ! load the new WIM<br>
                  nop; nop; nop<br>
                  restore ! Two restores to get into the<br>
                  restore ! window to restore<br>
                  ldd [%sp + 0x00], %l0 ! First the local register set<br>
                  ldd [%sp + 0x08], %l2<br>
                  ldd [%sp + 0x10], %l4<br>
                  ldd [%sp + 0x18], %l6<br>
                  ldd [%sp + 0x20], %i0 ! Then the input registers<br>
                  ldd [%sp + 0x28], %i2<br>
                  ldd [%sp + 0x30], %i4<br>
                  ldd [%sp + 0x38], %i6<br>
                  save ! Get back to the trap window.<br>
                  save<br>
                  jmp %l1 ! Re-execute restore.<br>
                  rett %l2
          <div><br>
          </div>
          <div>From my understanding this code should not ever
            fail, is that correct?</div>
          <div>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.</div>
          <div><br>
          </div>
          <div>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.</div>
          <div>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?</div>
          <div><br>
          </div>
          <div>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.</div>
          <div><br>
          </div>
          <div>I really hope someone can provide some knowledge
            on this type of issue.</div>
          -- <br>
          <div><span>
              <div><b><img><br>
                </b></div>
              <div>
                <b>Léonard Bise</b></div>
              <div>Software Design Engineer
              </div>
              <div>Direct Line <a href="tel:%2B41%20%280%2932%20338%209902" value="+41323389902" target="_blank">+41 (0)32 338 9902</a></div>
              <div><br>
              </div>
              <div><b>SYDERAL SA</b></div>
              <div>Neuenburgstrasse 7</div>
              <div>CH-3238 Gals (Switzerland)</div>
              <div>Desk Line <a href="tel:%2B41%20%280%2932%20338%209800" value="+41323389800" target="_blank">+41 (0)32 338 9800</a></div>
              <div>Web Site <a href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
            </span></div>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    </div></div><span class="HOEnZb"><font color="#888888"><pre cols="72">-- 
Joel Sherrill, Ph.D.             Director of Research & Development 
<a href="mailto:joel.sherrill@OARcorp.com" target="_blank">joel.sherrill@OARcorp.com</a>        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805 
Support Available                (256) 722-9985 </pre>
  </font></span></div>

</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span><div><b><img src="http://www.syderal.ch/images/syd_icons/mini-logo-syd.png"><br></b></div><div><b>Léonard Bise</b></div><div>Software Design Engineer
</div><div>Direct Line +41 (0)32 338 9902</div><div><br></div><div><b>SYDERAL SA</b></div><div>Neuenburgstrasse 7</div><div>CH-3238 Gals (Switzerland)</div><div>Desk Line +41 (0)32 338 9800</div><div>Web Site <a href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
</span></div>
</div>