2.6.11-rc4 built with gcc-3.4.3 works fine on my eMac.
Building with gcc-4.0.0 (20050220) however gives me a kernel
with dead USB, and thus no keyboard or mouse, but everything
else seems to be working.
A diff between dmesg on the two kernels has an interesting nugget:
--- dmesg-2.6.11-rc4-gcc343 2005-02-23 20:57:54.000000000 +0100
+++ dmesg-2.6.11-rc4-gcc400 2005-02-23 21:14:44.000000000 +0100
@@ -1,5 +1,5 @@
Total memory = 256MB; using 512kB for hash table (at c0300000)
-Linux version 2.6.11-rc4-gcc343 (mikpe@darwin) (gcc version 3.4.3) #1 Wed Feb 23 20:53:57 CET 2005
+Linux version 2.6.11-rc4-gcc400 (mikpe@darwin) (gcc version 4.0.0 20050220 (experimental)) #1 Wed Feb 23 21:10:27 CET 2005
Found UniNorth memory controller & host bridge, revision: 210
Mapped at 0xfdf00000
Found a Intrepid mac-io controller, rev: 0, mapped at 0xfde80000
@@ -26,11 +26,11 @@
OpenPIC timer frequency is 4.160000 MHz
PID hash table entries: 2048 (order: 11, 32768 bytes)
GMT Delta read from XPRAM: 0 minutes, DST: off
-time_init: decrementer frequency = 41.600661 MHz
+time_init: decrementer frequency = 41.600571 MHz
Console: colour dummy device 80x25
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
-Memory: 255872k available (1788k kernel code, 976k data, 144k init, 0k highmem)
+Memory: 255872k available (1776k kernel code, 0k data, 144k init, 0k highmem)
AGP special page: 0xcffff000
Calibrating delay loop... 830.66 BogoMIPS (lpj=4153344)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
@@ -132,13 +132,7 @@
VFS: Mounted root (ext3 filesystem) readonly.
Freeing unused kernel memory: 144k init 4k chrp 8k prep
usb 3-2: new full speed USB device using ohci_hcd and address 2
-hub 3-2:1.0: USB hub found
-hub 3-2:1.0: 3 ports detected
-usb 3-2.1: new low speed USB device using ohci_hcd and address 3
-input: USB HID v1.10 Mouse [Logitech Apple Optical USB Mouse] on usb-0001:10:1b.0-2.1
-usb 3-2.3: new full speed USB device using ohci_hcd and address 4
-input: USB HID v1.10 Keyboard [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
-input: USB HID v1.10 Device [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
+usb 3-2: can't connect bus-powered hub to this port
EXT3 FS on hda5, internal journal
Adding 1048568k swap on /dev/hda3. Priority:-1 extents:1
SCSI subsystem initialized
Note: "Memory: ... 0k data ..." !? Surely that can't be correct.
/Mikael
> -Memory: 255872k available (1788k kernel code, 976k data, 144k init, 0k highmem)
> +Memory: 255872k available (1776k kernel code, 0k data, 144k init, 0k highmem)
That is weird... (0k data)
> AGP special page: 0xcffff000
> Calibrating delay loop... 830.66 BogoMIPS (lpj=4153344)
> Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
> @@ -132,13 +132,7 @@
> VFS: Mounted root (ext3 filesystem) readonly.
> Freeing unused kernel memory: 144k init 4k chrp 8k prep
> usb 3-2: new full speed USB device using ohci_hcd and address 2
> -hub 3-2:1.0: USB hub found
> -hub 3-2:1.0: 3 ports detected
> -usb 3-2.1: new low speed USB device using ohci_hcd and address 3
> -input: USB HID v1.10 Mouse [Logitech Apple Optical USB Mouse] on usb-0001:10:1b.0-2.1
> -usb 3-2.3: new full speed USB device using ohci_hcd and address 4
> -input: USB HID v1.10 Keyboard [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
> -input: USB HID v1.10 Device [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
> +usb 3-2: can't connect bus-powered hub to this port
> EXT3 FS on hda5, internal journal
> Adding 1048568k swap on /dev/hda3. Priority:-1 extents:1
> SCSI subsystem initialized
>
> Note: "Memory: ... 0k data ..." !? Surely that can't be correct.
Not sure what's up, but it's probably something beeing miscompiled. Can
you check if the udelay/medlay loops are correct ?
Ben.
Benjamin Herrenschmidt writes:
> > -Memory: 255872k available (1788k kernel code, 976k data, 144k init, 0k highmem)
> > +Memory: 255872k available (1776k kernel code, 0k data, 144k init, 0k highmem)
>
> That is weird... (0k data)
>
> > AGP special page: 0xcffff000
> > Calibrating delay loop... 830.66 BogoMIPS (lpj=4153344)
> > Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
> > @@ -132,13 +132,7 @@
> > VFS: Mounted root (ext3 filesystem) readonly.
> > Freeing unused kernel memory: 144k init 4k chrp 8k prep
> > usb 3-2: new full speed USB device using ohci_hcd and address 2
> > -hub 3-2:1.0: USB hub found
> > -hub 3-2:1.0: 3 ports detected
> > -usb 3-2.1: new low speed USB device using ohci_hcd and address 3
> > -input: USB HID v1.10 Mouse [Logitech Apple Optical USB Mouse] on usb-0001:10:1b.0-2.1
> > -usb 3-2.3: new full speed USB device using ohci_hcd and address 4
> > -input: USB HID v1.10 Keyboard [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
> > -input: USB HID v1.10 Device [Mitsumi Electric Apple Extended USB Keyboard] on usb-0001:10:1b.0-2.3
> > +usb 3-2: can't connect bus-powered hub to this port
> > EXT3 FS on hda5, internal journal
> > Adding 1048568k swap on /dev/hda3. Priority:-1 extents:1
> > SCSI subsystem initialized
> >
> > Note: "Memory: ... 0k data ..." !? Surely that can't be correct.
>
> Not sure what's up, but it's probably something beeing miscompiled. Can
> you check if the udelay/medlay loops are correct ?
Both __delay and a few test functions using udelay/mdelay look Ok.
_However_, the 0k data message is due to a gcc-4.0 bug, and below
you'll find a test program which illustrates it.
/Mikael
/* gcc4bug.c
* Written by Mikael Pettersson <[email protected]>, 2005-02-24.
*
* This program is abstracted from arch/ppc/mm/init.c in
* the 2.6.11-rc4 Linux kernel sources.
*
* With gcc-3.4.3, gcc-3.3.5, or gcc-3.2.3, mem_init()
* correctly returns 245.
*
* With gcc-4.0.0 20050220, mem_init() erroneously returns 0.
* The error occurs with -O1, and -O2.
* Compiling at -O0, or -O3 or higher, hides the error.
*
* All gcc versions were configured for powerpc-unknown-linux-gnu.
*/
#include <stdio.h>
#define PAGE_SIZE 4096
unsigned long PAGE_OFFSET;
unsigned long high_memory;
unsigned long etext;
unsigned long init_begin;
unsigned long init_end;
unsigned long klimit;
int mem_init(void)
{
unsigned long addr;
int codepages = 0;
int datapages = 0;
int initpages = 0;
for (addr = PAGE_OFFSET; addr < high_memory; addr += PAGE_SIZE) {
if (addr < etext)
codepages++;
else if (addr >= init_begin && addr < init_end)
initpages++;
else if (addr < klimit)
datapages++;
}
printf("datapages == %d, initpages == %d, codepages == %d\n", datapages, initpages, codepages);
return datapages;
}
int main(void)
{
int datapages;
PAGE_OFFSET = 0xc0000000;
etext = 0xc01bb958;
init_begin = 0xc0264000;
init_end = 0xc0288000;
klimit = 0xc02d4378;
high_memory = 0xd0000000;
datapages = mem_init();
if (datapages != 245) {
fprintf(stderr, "gcc bug! mem_init() returned %d\n", datapages);
return 1;
} else
return 0;
}
On Thu, Feb 24, 2005 at 04:08:47PM +0100, Mikael Pettersson wrote:
> /* gcc4bug.c
> * Written by Mikael Pettersson <[email protected]>, 2005-02-24.
...
Reproduced, thanks for the testcase. Looking into it...
Jakub
On Thu, Feb 24, 2005 at 04:08:47PM +0100, Mikael Pettersson wrote:
> _However_, the 0k data message is due to a gcc-4.0 bug, and below
> you'll find a test program which illustrates it.
http://gcc.gnu.org/PR20196
Jakub
Jakub Jelinek writes:
> On Thu, Feb 24, 2005 at 04:08:47PM +0100, Mikael Pettersson wrote:
> > _However_, the 0k data message is due to a gcc-4.0 bug, and below
> > you'll find a test program which illustrates it.
>
> http://gcc.gnu.org/PR20196
Jakub's patch to gcc4 solved the mysterious "0k data" message,
but my eMac's USB is still dysfunctional. I'll try to look into
that next week.
/Mikael
Mikael Pettersson writes:
> Jakub Jelinek writes:
> > On Thu, Feb 24, 2005 at 04:08:47PM +0100, Mikael Pettersson wrote:
> > > _However_, the 0k data message is due to a gcc-4.0 bug, and below
> > > you'll find a test program which illustrates it.
> >
> > http://gcc.gnu.org/PR20196
>
> Jakub's patch to gcc4 solved the mysterious "0k data" message,
> but my eMac's USB is still dysfunctional. I'll try to look into
> that next week.
CONFIG_USB_DEBUG gave the following dmesg diff between gcc-3.4.3 and 4.0.0:
@@ -118,6 +118,8 @@
hub 1-0:1.0: Single TT
hub 1-0:1.0: TT requires at most 8 FS bit times
hub 1-0:1.0: power on to power good time: 20ms
+hub 1-0:1.0: hub controller current requirement: 0mA
+hub 1-0:1.0: 500mA bus power budget for children
hub 1-0:1.0: local power source is good
hub 1-0:1.0: enabling power on all ports
ohci_hcd: 2004 Nov 08 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI)
There are several more of these diffs, and they are what's eventually
causing USB to label the hub as bus-powered and refuse to connect it.
The root problem is that code like:
get_status(..., &status);
cpu_to_le16s(&status);
if ((status & (1 << BITNO)) == 0) { ... }
gets miscompiled so that the if statement triggers when it shouldn't.
Below is a standalone test program which reproduces the bug.
It does involve some PPC-specific asm(), so the bug may be
in gcc-4.0.0 or it may be in the asm() constraints.
/Mikael
/* gcc4bug2.c
* Written by Mikael Pettersson <[email protected]>, 2005-02-25.
*
* This program is abstracted from drivers/usb/core/hub.c in
* the 2.6.11-rc5 Linux kernel sources.
*
* With gcc-3.4.3, gcc-3.3.5, or gcc-3.2.3, usb_configure()
* correctly returns 0.
*
* With gcc-4.0.0 20050220, usb_configure() erroneously returns 1.
* The error occurs at -O1 and higher. -O0 hides the error.
*
* All gcc versions were configured for powerpc-unknown-linux-gnu.
*/
#include <stdio.h>
extern __inline__ __attribute__((always_inline))
void st_le16(volatile unsigned short *addr, const unsigned val)
{
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
static __inline__ __attribute__((always_inline))
void swab16s(unsigned short *addr)
{
st_le16(addr, *addr);
}
unsigned short raw_hubstatus;
void usb_get_status(unsigned short *hubstatusp)
{
*hubstatusp = raw_hubstatus;
}
int usb_configure(void)
{
unsigned short hubstatus;
usb_get_status(&hubstatus);
swab16s(&hubstatus);
return (hubstatus & 1) == 0;
}
int main(void)
{
int ret;
raw_hubstatus = 0x0300;
ret = usb_configure();
if (ret) {
fprintf(stderr, "gcc bug! usb_configure() returned %d\n", ret);
return 1;
} else
return 0;
}