[U-Boot] Question about ARM compiler optimization problem
Choe, Hyun-ho
firebird at legend.co.kr
Fri Nov 21 15:35:09 CET 2008
After I looked into disassembled ARM codes, found no reason to cause
problem.
When I compiled with -Os option, the C source code like following:
static int flash_toggle (flash_info_t * info, flash_sect_t sect,
uint offset, uchar cmd)
{
void *addr;
cfiword_t cword;
int retval;
addr = flash_map (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
retval = flash_read8(addr) != flash_read8(addr);
break;
case FLASH_CFI_16BIT:
retval = flash_read16(addr) != flash_read16(addr);
break;
case FLASH_CFI_32BIT:
retval = flash_read32(addr) != flash_read32(addr);
break;
case FLASH_CFI_64BIT:
retval = flash_read64(addr) != flash_read64(addr);
break;
default:
retval = 0;
break;
}
flash_unmap(info, sect, offset, addr);
return retval;
}
is compiled as following:
f0497c: e1a0100a mov r1, sl
f04980: e3a02000 mov r2, #0 ; 0x0
f04984: e1a00007 mov r0, r7
f04988: ebfffcbc bl f03c80 <flash_map>
f0498c: e3a01040 mov r1, #64 ; 0x40
f04990: e1a04000 mov r4, r0
f04994: e28d2004 add r2, sp, #4 ; 0x4
f04998: e1a00007 mov r0, r7
f0499c: ebfffcbd bl f03c98 <flash_make_cmd>
f049a0: e5d732af ldrb r3, [r7, #687]
f049a4: e2433001 sub r3, r3, #1 ; 0x1
f049a8: e3530007 cmp r3, #7 ; 0x7
f049ac: 979ff103 ldrls pc, [pc, r3, lsl #2]
f049b0: ea000022 b f04a40 <.text+0x4a40>
f049b4: 00f049d4 ldreqsbt r4, [r0], #148
f049b8: 00f049e0 rsceqs r4, r0, r0, ror #19
f049bc: 00f04a40 rsceqs r4, r0, r0, asr #20
f049c0: 00f049ec rsceqs r4, r0, ip, ror #19
f049c4: 00f04a40 rsceqs r4, r0, r0, asr #20
f049c8: 00f04a40 rsceqs r4, r0, r0, asr #20
f049cc: 00f04a40 rsceqs r4, r0, r0, asr #20
f049d0: 00f04a00 rsceqs r4, r0, r0, lsl #20
f049d4: e5d42000 ldrb r2, [r4]
f049d8: e5d43000 ldrb r3, [r4]
f049dc: ea000004 b f049f4 <.text+0x49f4>
f049e0: e1d420b0 ldrh r2, [r4]
f049e4: e1d430b0 ldrh r3, [r4]
f049e8: ea000001 b f049f4 <.text+0x49f4>
f049ec: e5942000 ldr r2, [r4]
f049f0: e5943000 ldr r3, [r4]
f049f4: e0520003 subs r0, r2, r3
f049f8: 13a00001 movne r0, #1 ; 0x1
f049fc: ea00000d b f04a38 <.text+0x4a38>
f04a00: e59f317c ldr r3, [pc, #380] ; f04b84 <.text+0x4b84>
f04a04: e1a00004 mov r0, r4
f04a08: e1a0e00f mov lr, pc
f04a0c: e1a0f003 mov pc, r3
f04a10: e59f216c ldr r2, [pc, #364] ; f04b84 <.text+0x4b84>
f04a14: e1a05000 mov r5, r0
f04a18: e1a00004 mov r0, r4
f04a1c: e1a06001 mov r6, r1
f04a20: e1a0e00f mov lr, pc
f04a24: e1a0f002 mov pc, r2
f04a28: e1550000 cmp r5, r0
f04a2c: 1affff98 bne f04894 <flash_full_status_check+0x28>
f04a30: e1560001 cmp r6, r1
f04a34: ea000000 b f04a3c <.text+0x4a3c>
f04a38: e3500000 cmp r0, #0 ; 0x0
f04a3c: 1affff94 bne f04894 <flash_full_status_check+0x28>
f049d4 ~ f049f0 is accessing flash_read8/16/32 functions, and this code
should be work because two sequential read from CFI flash changes toggle
bit while erase/write is in action.
But, two read operation gets the same result.
Any other things that I wasn't understand ?
TIA, Any advice will be appreciated.
Best regards,
Choe, Hyun-ho
2008-11-20 (목), 12:34 -0600, Andrew Dyer 쓰시길:
> On Thu, Nov 20, 2008 at 11:59 AM, Choe, Hyun-ho <firebird at legend.co.kr> wrote:
> > In cpu dir, there is arm920t/ks8695.
> > ks8695p is some modified chip from ks8695.
> >
> > In board section, OpenGear cm4008 and cm41xx uses ks8695.
> >
> >
>
> I would guess the problem is that the compiler is reading the hardware
> once and using that value both times, thinking that the location is
> memory, not a hardware register, where the value may change from time
> to time.
> I've always fixed this with a 'volatile' pointer, which is supposed to
> force the compiler to read the location every time it is accessed.
> Supposedly the 'linux way' is to use special accessor functions that
> are written to prevent this optimization from occurring.
>
> The other problem I've seen with toggle registers is reading them on
> hardware that likes to do multiple reads to fill up a word of data.
> For example you have a 16 bit flash on a 32-bit bus, and you read the
> status register as a 32-bit quantity, then the hardware goes and reads
> the register twice to fill up the 32-bit request, and the next time
> you read you see the same data again as the first time through because
> the value with the toggle in it is in the other half of the first
> 32-bits you fetched.
More information about the U-Boot
mailing list