On 03/23/2015 10:23 PM, Leo Yan wrote:
On Mon, Mar 23, 2015 at 02:25:15PM +0000, Leo Yan wrote:
On Fri, Mar 20, 2015 at 07:22:27AM +0000, Fathi Boudra wrote:
On 19 March 2015 at 20:18, Jerome Forissier jerome.forissier@linaro.org wrote:
[...]
If I change address to 0x4, the code goes past this location but later hangs with the same LED status as above (b0100) and code "0000000096000021" on the console. This is bug #2.
I tracked it down to the initialization of some structures on the stack when entering usb_handle_control_request() [6]. Looks like an alignment issue, since removing the packed attribute on struct usb_endpoint_descriptor [7] fixes the bug.
W/t Peter and Jorge's reminding, below are my analysis for th error for "0000000096000021":
From ARMv8-ARM D7.2.27, we can know the exception class (EC) is b'100101, that means this error is caused by below errors:
"Data Abort that caused entry from a current exception level (AArch64). Used for data access generated MMU faults, alignment faults other than those caused by the Stack Pointer misalignment, and synchronous external aborts, including synchronous parity errors. Not used for debug related exceptions."
So this error is highly related w/t alignment issue.
After print out the ELR_EL3, then can get the PC value when the exception happened, ELR_EL3 = 0xf980_5be4, so from objdump file get below code section; in this case X2=0x00000000f980b018, but in the instruction the offset = 0x3; so finally it will trigger unalignent issue...
--->8--- 5434 f9805bdc: b9004ba4 str w4, [x29,#72] 5435 f9805be0: 52800400 mov w0, #0x20 // #32 5436 f9805be4: b8403044 ldr w4, [x2,#3]
And use "addr2line" can get to know the error is happened to access the usb structure at line 729:
694 void usb_handle_control_request(setup_packet* req) 695 { 696 const void* addr = NULL; 697 int size = -1; 698 int maxpacket; 699 unsigned int data; 700 struct usb_endpoint_descriptor epx; 701 struct usb_config_bundle const_bundle = { 702 .config = { 703 .bLength = sizeof(struct usb_config_descriptor), 704 .bDescriptorType = USB_DT_CONFIG, 705 .wTotalLength = sizeof(struct usb_config_descriptor) + 706 sizeof(struct usb_interface_descriptor) + 707 sizeof(struct usb_endpoint_descriptor) * 708 USB_NUM_ENDPOINTS, 709 .bNumInterfaces = 1, 710 .bConfigurationValue = 1, 711 .iConfiguration = 0, 712 .bmAttributes = USB_CONFIG_ATT_ONE, 713 .bMaxPower = 0x80 714 }, 715 .interface = { 716 .bLength = sizeof(struct usb_interface_descriptor), 717 .bDescriptorType = USB_DT_INTERFACE, 718 .bInterfaceNumber = 0, 719 .bAlternateSetting = 0, 720 .bNumEndpoints = USB_NUM_ENDPOINTS, 721 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 722 .bInterfaceSubClass = 0x42, 723 .bInterfaceProtocol = 0x03, 724 .iInterface = 0 725 } 726 }; 727 728 /* avoid to hang on accessing unaligned memory */ 729 struct usb_endpoint_descriptor const_ep1 = { 730 .bLength = sizeof(struct usb_endpoint_descriptor), 731 .bDescriptorType = USB_DT_ENDPOINT, 732 .bEndpointAddress = 0x81, 733 .bmAttributes = USB_ENDPOINT_XFER_BULK, 734 .wMaxPacketSize = 0, 735 .bInterval = 0 736 };
the linux kernel recommends the following when initializing endpoint descriptors so I would be reluctant to remove the packed attribute.
* Note all descriptors are declared '__attribute__((packed))' so that: * * [a] they never get padded, either internally (USB spec writers * probably handled that) or externally; * * [b] so that accessing bigger-than-a-bytes fields will never * generate bus errors on any platform, even when the location of * its descriptor inside a bundle isn't "naturally aligned", and * * [c] for consistency, removing all doubt even when it appears to * someone that the two other points are non-issues for that * particular descriptor type.
at the same time
/* USB_DT_ENDPOINT: Endpoint descriptor */ struct usb_endpoint_descriptor { __u8 bLength; __u8 bDescriptorType;
__u8 bEndpointAddress; __u8 bmAttributes; __le16 wMaxPacketSize; __u8 bInterval;
/* NOTE: these two are _only_ in audio endpoints. */ * /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */* __u8 bRefresh; __u8 bSynchAddress; } __attribute__ ((packed));
#define USB_DT_ENDPOINT_SIZE 7 #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */