lkml.org 
[lkml]   [2005]   [Sep]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: aoe fails on sparc64
From
From: Ed L Cashin <ecashin@coraid.com>
Date: Fri, 16 Sep 2005 09:36:51 -0400

> I've been working with Jim MacBaine, and he reports that the patch
> below gets rid of the problem. I don't know why. When I test
> le64_to_cpup by itself, it works as expected.

This reminds me of a known UltraSPARC chip bug. There is a bug
wherein if you do a 64-bit endianness swapped load instruction, it
only endian swaps within each 32-bit word, not throughout the entire
64-bit word as it should.

But this is weird, because the errata description for this chip bug
says that it only applies to the deprecated 32-bit mode "ldd/std"
instructions, whereas the compiler emits the 64-bit "ldx/stx"
instructions for sparc64 kernel builds.

So, first, let's sanity check the ___arch__swab64p() implementation:

#include <stdlib.h>
#include <stdio.h>

#define ASI_PL 0x88 /* Primary, implicit, l-endian */
typedef unsigned long __u64;

static __inline__ __u64 ___arch__swab64p(const __u64 *addr)
{
__u64 ret;
__asm__ __volatile__ ("ldxa [%1] %2, %0"
: "=r" (ret)
: "r" (addr), "i" (ASI_PL));
return ret;
}
int main(void)
{
unsigned long tval = 0x123456789abcdef0;
unsigned long *p, v;
p = &tval;
v = ___arch__swab64p(p);
printf("%016lx --> %016lx\n",
tval, v);
exit(0);
}
Running this on my Ultra-IIIi workstation (this chip doesn't have
said errata) gives the desired result:

davem@sunset:~/src/GIT/sparc-2.6$ gcc -m64 -O2 -o x x.c
davem@sunset:~/src/GIT/sparc-2.6$ ./x
123456789abcdef0 --> f0debc9a78563412
davem@sunset:~/src/GIT/sparc-2.6$

So it looks sane. Let's try this on a chip that has the errata:

? ./x
123456789abcdef0 --> f0debc9a78563412
?

That's fine too, so this isn't what is causing the problems.

Wait, I think I see the problem. Is that "&id[100<<1]" pointer
aligned properly on a 64-bit boundary? I bet it isn't, and the
sparc64 unaligned load/store trap handler doesn't check whether one of
the endian swapping load/store attributes are being used.

Looking at the assembler generated for aoecmd.s, it isn't aligned:

add %l1, 236, %g2
...
ldxa [%g2] 136, %g7

That's aligned on a 4-byte boundary, but not an 8-byte one.

So this is what the bug is.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-09-16 22:39    [from the cache]
©2003-2011 Jasper Spaans