MIPS questions

gregory.menke at gsfc.nasa.gov gregory.menke at gsfc.nasa.gov
Fri Oct 24 21:57:16 UTC 2003


Jay Monkman writes:
 > On Fri, Oct 24, 2003 at 02:18:02PM -0400, gregory.menke at gsfc.nasa.gov wrote:
 > > 
 > > Jay Monkman writes:
 > >  > I'm working on a MIPS BSP, and have a couple questions.
 > >  > 
 > >  > Does anybody have TCP/IP working? Unless I make changes, I get
 > >  > alignment errors. During processing, the stack overlays the TCP source
 > >  > and dest port numbers with the address of the mbuf. Since there's no
 > >  > guarantee those stay aligned, how is TCP working on MIPS? It looks
 > >  > like the fixes we put in for ARM will fix this also.
 > > 
 > > Could you be more specific here?  What driver are you using, where is
 > > the alignment error happening, etc...
 > 
 > It's a new driver for the Au1500. I don't remember where I catch the
 > error, but the macro REASS_MBUF is what does the overlaying. There's a
 > handful of places in tcp_input.c where it happens. The device I'm
 > using causes the IP packet to be 2 bytes off of 4 byte alignment,
 > since the ethernet header is 14 bytes long. This ensures the source
 > and destination ports in the TCP header are misaligned (unless there
 > are IP options?). Does TCP work on any other MIPS CPUs? Do they have
 > misaligned IP packets? Is this only a problem on MIPS32?

The 2 byte offset seems a common optimization to put the ip header on
a paragraph boundary- Linux people do it in drivers sometimes.  gcc is
<supposed> to be handling alignment, but whatever the mbuff stuff is
doing might be sneaking around it.  Could you give an example line #
so I can look at it directly?
 
 
 > >  > 
 > >  > In _CPU_ISR_Set_level in cpukit/score/cpu/mips/cpu.c, there's a chunk
 > >  > of code:
 > >  >   sr = srbits | ((new_level==0)? (0xfc00 | SR_EXL | SR_IE): \
 > >  >                  (((new_level<<9) & 0xfc00) | \
 > >  >                   (new_level & 1)?(SR_EXL | SR_IE):0));
 > >  > 
 > >  > I think there needs to be parentheses around the last line. Without
 > >  > the parentheses, the statement turns into:
 > >  >   sr = srbits | ((new_level==0)? (0xfc00 | SR_EXL | SR_IE): \
 > >  >	             (SR_EXL | SR_IE));
 > >  > 
 > >  > Or am I missing something?
 > > 
 > > I think you're missing something, the false term of the first ?: is in
 > > parens.  The 9 bit rightshift and mask yields a constant or'ed into
 > > the expression.  The 2nd ?: tests for 1, which if false yields 0
 > > else the (SR_EXL | SR_IE).  But it is kind of messy and extra parens
 > > would be helpful.
 > 
 > Is the second test supposed to be
 >      (new_level & 1)
 > or
 >      ( (new_level<<9) & 0xfc00) | (new_level & 1)
 > 
 > I think according to C's precedence rules ( '|' is higher than '?:') ,
 > the test is the latter, but we want the former.
 > 

The messiness messed me up... sorry about that.  The expression should be;

 sr = srbits | ( (new_level==0)? (0xfc00 | SR_EXL | SR_IE):
		                 ( ((new_level<<9) & 0xfc00) | \
				     ((new_level & 1)?(SR_EXL | SR_IE):0) ) );

This is R4000 code, which is in a lightly tested state right now.  You
should pay particular attention to anything interrupt-enabled, all the
interrupt level set/get functions for example.

Gregm





More information about the users mailing list