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    [W:0.038 / U:0.488 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site