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