[U-Boot] packed attribute problem
Balau
balau at users.sourceforge.net
Mon Oct 4 14:50:03 CEST 2010
Dear Wolfgang Denk and Reinhard Meyer,
The compiler (4.4.1) generates the expected 32bit store instruction when using:
struct p {
int n;
} __attribute__ ((packed, aligned(4)));
In case of hardware registers, I have yet to see a case where this is not true.
Regards,
Francesco
On Mon, Oct 4, 2010 at 2:43 PM, Reinhard Meyer <u-boot at emk-elektronik.de> wrote:
> Dear Wolfgang Denk,
>
>> Dear Reinhard Meyer,
>>
>> In message <4CA9BE94.6000401 at emk-elektronik.de> you wrote:
>>> Do you imply that the code is really different when the pointer gets
>>> its value by assigning it NOT to a packed entity? Hard to believe.
>>
>> This is a special "feature" of GCC on ARM.
>>
>> -> cat foo.c
>> #define writel(v,a) (*(volatile unsigned int *)(a) = (v))
>>
>> struct p {
>> int n;
>> } __attribute__ ((packed));
>>
>> struct q {
>> int n;
>> };
>>
>> void foo()
>> {
>> struct p *pp = (struct p *)0x1000;
>>
>> pp->n = 5;
>> }
>>
>> void bar()
>> {
>> struct q *qq = (struct q *)0x1000;
>>
>> qq->n = 5;
>> }
>> -> arm-linux-gcc -O -S foo.c
>> -> cat foo.s
>> .file "foo.c"
>> .text
>> .align 2
>> .global foo
>> .type foo, %function
>> foo:
>> @ Function supports interworking.
>> @ args = 0, pretend = 0, frame = 0
>> @ frame_needed = 0, uses_anonymous_args = 0
>> @ link register save eliminated.
>> @ lr needed for prologue
>> mov r3, #4096
>> mov r2, #0
>> orr r1, r2, #5
>> strb r1, [r3, #0]
>> strb r2, [r3, #1]
>> strb r2, [r3, #2]
>> strb r2, [r3, #3]
>> bx lr
>> .size foo, .-foo
>> .align 2
>> .global bar
>> .type bar, %function
>
> In a non-packed struct an int will never be unaligned
> (unless you use an unaligned pointer to the whole struct)
>
> In a packed struct an int might be unaligned, so it
> _might_ make sense for the compiler to handle that
> differently on ARM. Assume you overlay (bad idea anyway)
> a packed structure over some communication data stream
> thats is byte oriented. On most architectures that would
> work (besides obvious endianess issues) but on ARM it would
> (without raising an exception) malfunction.
> [remember the "display_buffer issue"]
>
>> bar:
>> @ Function supports interworking.
>> @ args = 0, pretend = 0, frame = 0
>> @ frame_needed = 0, uses_anonymous_args = 0
>> @ link register save eliminated.
>> @ lr needed for prologue
>> mov r2, #5
>> mov r3, #4096
>> str r2, [r3, #0]
>> bx lr
>> .size bar, .-bar
>> .ident "GCC: (GNU) 4.2.2"
>>
>>
>> Note that this is with GCC 4.2.2. Even GCC 4.0.0 behaves the same, so
>> this is *not* an issue with very recent tool chains.
>
> OK, for directly adressing elements inside a packed struct;
> but the original post said:
>
> "struct xyz {
> int x;
> int y;
> int z[CONST];
> } __attribute__ ((packed));
>
> struct xyz *abc;
> u32 * status_reg = (u32 *)&abc->z[0];
>
> writel(status, status_reg);"
>
> So the "status_reg" pointer is in a completely unrelated (to the packed struct)
> "u32 *" and still the access is done like it was packed. If the
> compiler silently drags that attribute along into the "u32 *"
> THAT is really sick!
>
> Reinhard
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
More information about the U-Boot
mailing list