[U-Boot] [Resend RFC PATCH v2 0/1] MIPS64 timer bug

Chris Packham
2015-07-14T10:54:40Z

We found this on a custom MIPS64 based board. Basically we were seeing
udelay and friends do odd things occasionally. The problem appears to be
when we read the c0 32-bit counter sometimes we get unexpected values
when this is returned as an unsigned long on a 64-bit system. I've
written a little test program (below) that demonstrates the what I think
is problem, it'll work on a x86_64 desktop. I don't know the ins and
outs of the C specifications to comment on if this is a compiler bug but
I still think we should be treating the c0 registers as unsigned
regardless.

$ cat test.c
#include <stdio.h>

int main(int argc, char *argv[])
{
int a;
unsigned long b;

a = 0x80000000;
b = a;

printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(unsigned long) = %zu\n", sizeof(unsigned long));
printf("a = %d\n", a);
printf("a = %x\n", a);
printf("b = %lu\n", b);
printf("b = %lx\n", b);

return 0;
}

Which yields the following output

$ ./test
sizeof(int) = 4
sizeof(unsigned long) = 8
a = -2147483648
a = 80000000
b = 18446744071562067968
b = ffffffff80000000

And for completeness
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.

Our embedded target is using
$ mips64-octeon-linux-gnu-gcc --version
mips64-octeon-linux-gnu-gcc (GCC) 4.7.0
Copyright (C) 2012 Free Software Foundation, Inc.

Changes in v2:
- Use Rob's current email address

Chris Packham (1):
mips: Use unsigned int when reading c0 registers

arch/mips/include/asm/mipsregs.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--
2.5.0.rc0