[U-Boot] Alignment bug in itest on ARM & doesn't work on big-endian either?

Tom Evans
2009-03-04T00:19:08Z

Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> wrote:
> On 17:40 Tue 03 Mar , Tom Evans wrote:
>> BUG IN ITEST
>> ------------
>> itest crashes ARM chips. I can "iread.b *82000000 == 0",
>> but "iread.b *82000001 == 0" throws an alignment
>> exception that kills the box. The code in itest.c is:
>>
>> static long evalexp(char *s, int w)
>> {
>> long l, *p;
>>
>> /* if the parameter starts with a * then assume
>> is a pointer to the value we want */
>> if (s[0] == '*') {
>> p = (long *)simple_strtoul(&s[1], NULL, 16);
>> l = *p;

> here you are support to use the good accessor
> readb/readw/readl

Thank you for your response.

readl() is defined in asm-arm/io.h as "__arch_getl(a)" which
is defined as "(*(volatile unsigned int *)(a))" which
doesn't handle misalignment and will still crash.

I think those functions are only meant for I/O reads.

The code then "selects the byte" with the following:

>> return (l & ((1 << (w * 8)) - 1));

That selects the LOWER 8/16/32 bits of the 32-bit read.

Which works on a 486, ARM variants with unaligned transfers, but NOT on
a PPC or any other big-endian CPUs (about half of them supported by U-Boot).

On a big-endian unaligned supporting CPU I'd expect a byte read of
address "0" to read "3" and a read of "1" to read "4" (in the next
word!). Ditto for itest.w.

Whoever owns/maintains this code, and/or can test it on a big-endian
target should fix these, taking hints from the cmd_mem.c code which does
all of this in a portable manner. I don't have a big-endian target so I
can't test the big-endian fix.

> the arm does not allow you to do an non aligned access

I know that. The current itest code doesn't. The "indirect pointer
feature" mustn't be used much if I'm the first one to find these problems.

--
===
Tom Evans Tom.Evans at ceos.com.au
CEOS Pty Ltd www.ceos.com.au
3/17 Burgundy St, Heidelberg,
Victoria 3084, Australia