<div dir="ltr">This is a lot better. As Joel said, there is still a problem if an interrupt can come. For that you should use a general timer if available. Also, I made one comment below.<br><div><div class="gmail_extra"><br>
<br><div class="gmail_quote">On Wed, Apr 24, 2013 at 5:54 AM, Leonard Bise <span dir="ltr"><<a href="mailto:leonard.bise@syderal.ch" target="_blank">leonard.bise@syderal.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<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><div class="im"><p 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 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 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></div><p 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 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>
<div class="im">
<p 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>
</div><p 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 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 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 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));</span></p>
</div></div></div></blockquote><div>While this should work, the count variable is actually an input here, so you really just need<br></div><div>__asm__ __volatile__("cmp %0, 0" : : "r" (count));<br></div>
<div> <br></div><div>As always, check the output of the assembler pass to make sure your function looks like how you expect. The compiler could (in theory) move data between memory and register within this code block.<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><p 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 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 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 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 style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE">/*#]*/<u></u><u></u></span></p>
<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE"> }<u></u><u></u></span></p><p style="font-family:arial,sans-serif;font-size:13px">
<span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE">}</span></p></div></div></div><div class="HOEnZb"><div class="h5"><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><br>
<br>
On 4/23/2013 4:02 AM, Leonard Bise wrote:<br>
</div></div></div><div><div>
<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><b style="line-height:25px;font-size:18px;font-family:Helvetica,arial,freesans,clean,sans-serif;margin:0px;border:0px;padding:0px"><br>
</b></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><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 <a href="tel:%28256%29%20722-9985" value="+12567229985" target="_blank">(256) 722-9985</a> </pre>
</font></span></div>
</blockquote></div><br><br clear="all"><div><br></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></div><br>_______________________________________________<br>
rtems-users mailing list<br>
<a href="mailto:rtems-users@rtems.org">rtems-users@rtems.org</a><br>
<a href="http://www.rtems.org/mailman/listinfo/rtems-users" target="_blank">http://www.rtems.org/mailman/listinfo/rtems-users</a><br>
<br></blockquote></div><br></div></div></div>