On 23/03/15 14:25, 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 };
- Quick try: if move upper local variables (in stack?) to global varaibles (in data section?), then the issue also will dismiss.
Oops. I just ended up making pretty the same suggestion in the github issue tracker. Didn't mean to duplicate the conversation here.
Anyhow I would have expected adding a const qualifier to these structures to fix the issue (check that the compiled code memcpy's them directly from .rodata).
Daniel.