[poky] BeagleBoard using GCC 4.6.0
Gary Thomas
gary at mlbassoc.com
Thu Jun 9 15:37:49 PDT 2011
On 06/09/2011 04:33 PM, Darren Hart wrote:
>
>
> On 06/09/2011 04:32 AM, Gary Thomas wrote:
>> On 06/09/2011 05:20 AM, Gary Thomas wrote:
>>> On 06/09/2011 12:48 AM, Khem Raj wrote:
>>>> On 06/08/2011 07:24 PM, Gary Thomas wrote:
>>>>> On 06/08/2011 06:42 PM, Khem Raj wrote:
>>>>>> On 06/08/2011 11:20 AM, Saul Wold wrote:
>>>>>>> On 06/08/2011 10:43 AM, Gary Thomas wrote:
>>>>>>>> Now that Poky is using GCC 4.6.0, has anyone actually checked the
>>>>>>>> operation on the BeagleBoard? I suspect that you'll find that the
>>>>>>>> EHCI USB does not work. I can't really check here as I don't trust
>>>>>>>> the EHCI on my BeagleBoard rev C3 (not xM).
>>>>>>>>
>>>>>>>> That said, I've tried this new compiler (previously reported) on
>>>>>>>> my own OMAP/3530 board which uses the same 2.6.37 kernel (just not
>>>>>>>> the linux-yocto version). When I build my kernel with GCC 4.5.2,
>>>>>>>> it works perfectly, but fails with GCC 4.6.0 (I trust the hardware).
>>>>>>>>
>>>>>>>> I've isolated it down to at least the function 'ehci_hub_control'
>>>>>>>> (but I suspect the problem is more fundamental). Comparing the code
>>>>>>>> generated by the two compilers with the same source tree, this function
>>>>>>>> is dramatically different. I can see why it's failing, I just don't
>>>>>>>> know why the compiler is doing what it's doing.
>>>>>>>>
>>>>>>>
>>>>>>> Gary,
>>>>>>>
>>>>>>> I am not sure if Khem Raj is on this list, so I am forwarding it to him,
>>>>>>> he might have some insight.
>>>>>>>
>>>>>>> Sau!
>>>>>>>
>>>>>>>
>>>>>>>> The lines at drivers/usb/host/ehci-hub.c:841
>>>>>>>> case GetPortStatus:
>>>>>>>> if (!wIndex || wIndex> ports)
>>>>>>>> goto error;
>>>>>>>> wIndex--;
>>>>>>>> status = 0;
>>>>>>>> temp = ehci_readl(ehci, status_reg);
>>>>>>>>
>>>>>>>> are being compiled very differently.
>>>>>>>>
>>>>>>>> With GCC 4.5.2:
>>>>>>>> 0xc0229810<ehci_hub_control+672>: cmp r3, #0 ; 0x0
>>>>>>>> 0xc0229814<ehci_hub_control+676>: beq 0xc0229df8
>>>>>>>> <ehci_hub_control+2184>
>>>>>>>> 0xc0229818<ehci_hub_control+680>: cmp r3, r0
>>>>>>>> 0xc022981c<ehci_hub_control+684>: bgt 0xc0229df8
>>>>>>>> <ehci_hub_control+2184>
>>>>>>>> 0xc0229820<ehci_hub_control+688>: sub r8, r3, #1 ; 0x1
>>>>>>>> 0xc0229824<ehci_hub_control+692>: ldr r5, [r7, #4]
>>>>>>>> 0xc0229828<ehci_hub_control+696>: uxth r8, r8
>>>>>>>> 0xc022982c<ehci_hub_control+700>: dmb sy
>>>>>>>>
>>>>>>>> With GCC 4.6.0:
>>>>>>>> 0xc0221630<ehci_hub_control+808>: cmp r3, #0 ; 0x0
>>>>>>>> 0xc0221634<ehci_hub_control+812>: beq 0xc0221d7c
>>>>>>>> <ehci_hub_control+2676>
>>>>>>>> 0xc0221638<ehci_hub_control+816>: cmp r3, r0
>>>>>>>> 0xc022163c<ehci_hub_control+820>: bgt 0xc0221d7c
>>>>>>>> <ehci_hub_control+2676>
>>>>>>>> 0xc0221640<ehci_hub_control+824>: sub r7, r3, #1 ; 0x1
>>>>>>>> 0xc0221644<ehci_hub_control+828>: add r3, r11, #16 ; 0x10
>>>>>>>> 0xc0221648<ehci_hub_control+832>: add r3, r8, r3, lsl #2
>>>>>>>> 0xc022164c<ehci_hub_control+836>: uxth r7, r7
>>>>>>>> 0xc0221650<ehci_hub_control+840>: ldrb r5, [r3, #5]
>>>>>>>> 0xc0221654<ehci_hub_control+844>: ldrb r2, [r3, #4]
>>>>>>>> 0xc0221658<ehci_hub_control+848>: orr r5, r2, r5, lsl #8
>>>>>>>> 0xc022165c<ehci_hub_control+852>: ldrb r2, [r3, #6]
>>>>>>>> 0xc0221660<ehci_hub_control+856>: ldrb r3, [r3, #7]
>>>>>>>> 0xc0221664<ehci_hub_control+860>: orr r5, r5, r2, lsl #16
>>>>>>>> 0xc0221668<ehci_hub_control+864>: orr r5, r5, r3, lsl #24
>>>>>>>> 0xc022166c<ehci_hub_control+868>: dmb sy
>>>>>>>>
>>>>>>>> As you can see, the old compiler accesses the ehci status register
>>>>>>>> in a single access, the new compiler dances around and makes multiple
>>>>>>>> accesses, which in the end get very incorrect data (I think that this
>>>>>>>> register is like many which clear bits on reads).
>>>>>>>>
>>>>>>>> Any ideas where I can go with this? I'm really trying to keep up with
>>>>>>>> Poky/Yocto, but this move to GCC 4.6.0 has broken my ARM targets :-(
>>>>>>>> I do have PowerPC targets as well - they seem fine (from limited
>>>>>>>> testing)
>>>>>>>> with the new compiler.
>>>>>>>>
>>>>>>>> Note: if you want to see the whole function disassembly, look at
>>>>>>>> http://www.mlbassoc.com/poky/ehci_hub_control-disassembly-gcc-4.5.2
>>>>>>>> http://www.mlbassoc.com/poky/ehci_hub_control-disassembly-gcc-4.6.0
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>>
>>>>>>
>>>>>> OK. thanks for sending the sample code.
>>>>>> Can you add -fstrict-volatile-bitfields option to CFLAGS while
>>>>>> compiling this file or even the kernel for test sake ?
>>>>>> and see if the problem goes away ?
>>>>>
>>>>> Sorry, this doesn't seem to make any difference in the generated code.
>>>>> Hardly surprising as the register in question is a simple u32, not a
>>>>> bitfield.
>>>>>
>>>>
>>>> I reduced the testcase a bit further and it seems the bug is similar to http://gcc.gnu.org/bugzilla/PR45819
>>>>
>>>> but a bit different that in this case -fstrict-volatile-bitfields does not help
>>>>
>>>> a fix for this particular problem is
>>>>
>>>> diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h
>>>> index 6563802..b8c1833 100644
>>>> --- a/include/linux/usb/ehci_def.h
>>>> +++ b/include/linux/usb/ehci_def.h
>>>> @@ -194,7 +194,7 @@ struct ehci_dbg_port {
>>>> u32 data47;
>>>> u32 address;
>>>> #define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep))
>>>> -} __attribute__ ((packed));
>>>> +} __attribute__ ((packed,aligned(__alignof__(int))));
>>>>
>>>> #ifdef CONFIG_EARLY_PRINTK_DBGP
>>>> #include<linux/init.h>
>>>>
>>>>
>>>> since this particular structure all elements are integers but there might be more packed structures which have say char or short ints
>>>> and are not necessarily ordered in the descending order of alignment
>>>>
>>>> Try it out and see if it helps
>>>
>>> Yes, this does fix the problem :-) The EHCI USB port on the OMAP
>>> is working again.
>>
>> Note: it also works properly if the __attribute__ ((packed)) is simply removed.
>> Looking at the layout of this structure, I don't see what that attribute is
>> trying to accomplish - every item within the structure is u32[], so IMO there
>> is nothing to pack. Perhaps this observation can help the GCC folks figure
>> out why things are getting confused.
>
> I tried each of these and neither worked. I confirmed the kernel was
> indeed different after each build and that gcc 4.6.0 was being used (by
> adding CC --version to the kernel do_compile and checking it in the log).
>
> Gary, are you certain that you were building with 4.6.0 ? I've found it
> to be a bit tricky to switch back and forth between compilers.
Absolutely - this is a clean, from scratch, build 100% GCC 4.6.0
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
More information about the poky
mailing list