This patch fixes "Ooops, address error on load or ifetch!", caused by "usb" command on MIPS architecture. To reproduce the problem follow the following steps: 1. Build barebox for MIPS target with -O0 optimization flag: diff --git a/Makefile b/Makefile index 5a7fd5f..da9a8be 100644 --- a/Makefile +++ b/Makefile @@ -301,7 +301,7 @@ CPPFLAGS := -D__KERNEL__ -D__BAREBOX__ $(LINUXINCLUDE) -fno-builtin -ffre CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -Werror-implicit-function-declaration \ - -fno-strict-aliasing -fno-common -Os -pipe + -fno-strict-aliasing -fno-common -O0 -pipe AFLAGS := -D__ASSEMBLY__ LDFLAGS_barebox := -Map barebox.map 2. Plug in a usb flash drive. 3. Run the "usb" command: barebox@QEMU DUNA:/ usb -s USB: scanning bus for devices... &(dev->config.interface[0].ep_desc[0].wMaxPacketSize) = a042732a Bus 001 Device 001: ID 0000:0000 EHCI Host Controller &(dev->config.interface[0].ep_desc[0].wMaxPacketSize) = a0429f02 &(dev->config.interface[0].ep_desc[1].wMaxPacketSize) = a0429f0b Ooops, address error on load or ifetch! $ 0 : 00000000 00000000 a0429f0b a0429de4 $ 4 : 00000000 0000000a 00000000 000687e0 $ 8 : 00000000 00000000 00000000 fa000000 $12 : 00000001 00000004 00000000 00000000 $16 : 00000000 00000000 00000000 00000000 $20 : 00000000 00000000 00000000 00000000 $24 : 00000000 00000000 $28 : 00000000 a03ffb40 a03ffb40 a082e9f4 Hi : 00000000 Lo : 00000000 epc : a082ea38 ra : a082e9f4 Status: b4000002 Cause : 00008010 Config: 88d0c083 ### ERROR ### Please RESET the board ### The source of the error is the following line of code from the usb_parse_config() function: le16_to_cpus(&(dev->config.interface[ifno].ep_desc[epno].\ wMaxPacketSize)); Which tries to load half-word from an un-aligned address 0xa0429f0b stored in v0: a082ea38: 94420000 lhu v0,0(v0) 0xa0429f0b is an address of wMaxPacketSize member of a struct usb_endpoint_descriptor at offset 4: struct usb_endpoint_descriptor { __u8 bLength; __u8 bDescriptorType; __u8 bEndpointAddress; __u8 bmAttributes; __le16 wMaxPacketSize; __u8 bInterval; __u8 bRefresh; __u8 bSynchAddress; } __attribute__ ((packed)); The instances of the usb_endpoint_descriptor are stored in a "ep_desc" array: struct usb_interface { ... struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; }; Since the size of the usb_endpoint_descriptor is odd (9 bytes), the second element of the ep_desc array is un-aligned, as well as it's member wMaxPacketSize: Bus 001 Device 001: ID 0000:0000 EHCI Host Controller &(dev->config.interface[0].ep_desc[0].wMaxPacketSize) = a0429f02 &(dev->config.interface[0].ep_desc[1].wMaxPacketSize) = a0429f0b A possible fix to this problem is to make the size of the usb_endpoint_descriptor even. --- include/usb/ch9.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/usb/ch9.h b/include/usb/ch9.h index ab5d531..5b261e6 100644 --- a/include/usb/ch9.h +++ b/include/usb/ch9.h @@ -379,6 +379,7 @@ struct usb_endpoint_descriptor { /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ __u8 bRefresh; __u8 bSynchAddress; + __u8 fill; } __attribute__ ((packed)); #define USB_DT_ENDPOINT_SIZE 7 -- 2.1.4 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox