[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