<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">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<br>
<br>
On 4/23/2013 4:02 AM, Leonard Bise wrote:<br>
</div>
<blockquote
cite="mid:CA+8QPXCxv=CzDe+fKqJyMcpyQ6_otm7+E4BWVwU6B2whb-Xjtw@mail.gmail.com"
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 class="" style="border:none;padding:0cm"><span
style="font-size:9pt;font-family:'Courier New'">void
SCET_wait_2us(void)
{</span><span style="font-size:9pt;font-family:'Courier
New'"></span></p>
<p class="" 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 class="" 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 class="" 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 class="" 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 style="font-size:9pt;font-family:'Courier
New'"></span></p>
<p class="" 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 class="" style="border:none;padding:0cm"><span
style="font-size:9pt;font-family:'Courier New'">
</span><span
style="font-size:9pt;font-family:'Courier
New';color:red">save;
\</span><span
style="font-size:9pt;font-family:'Courier
New';color:black"></span></p>
<p class="" 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 class="" 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 class="" 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 class="" 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 class="" 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 class="" 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 class="" style="border:none;padding:0cm"><span
style="font-size:9pt;font-family:'Courier New'">
</span><span
style="font-size:9pt;font-family:'Courier
New';color:red">restore;
\</span><span
style="font-size:9pt;font-family:'Courier
New';color:black"></span></p>
<p class="" 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 class="" 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 class="" 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 class="" 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 style="">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 style="">
<br>
</div>
<div style="">Once this code was implemented we started seeing
random processor reset occurring in various contexts.</div>
<div><br>
</div>
<div style="">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 style=""><br>
</div>
<div style="">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 style="">
I copied the trap handler code below.</div>
<div style=""><br>
</div>
<div style="">RTEMS 4.8 branch</div>
file : rtems / c / src / lib / libcpu / sparc / reg_win /
window.S
<div style=""><strong class=""
style="margin:0px;padding:0px;border:0px;color:rgb(0,0,0);font-family:Helvetica,arial,freesans,clean,sans-serif;font-size:18px;line-height:25px"><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 style="">From my understanding this code should not ever
fail, is that correct?</div>
<div style="">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 style="">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 style="">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 style=""><br>
</div>
<div style="">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 style=""><br>
</div>
<div style="">I really hope someone can provide some knowledge
on this type of issue.</div>
-- <br>
<div><span>
<div><b><img moz-do-not-send="true"
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 moz-do-not-send="true"
href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
</span></div>
</div>
</div>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--
Joel Sherrill, Ph.D. Director of Research & Development
<a class="moz-txt-link-abbreviated" href="mailto:joel.sherrill@OARcorp.com">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>
</body>
</html>