-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CThunk for CM7 #2522
Add CThunk for CM7 #2522
Conversation
cc @c1728p9 |
Then in this manual p 3-35, |
Rebased with a fully working version. GCC was failing because this toolchain define the |
Cc @meriac for any suggestions. According to the manual for Cortex-M4, Cortex-M3 and Cortex-M7, |
Since the documentation for M3 and M4 don't allow the PC to be used to as the address to load from in a LDM instruction should all the targets be using the M0 implementation? @meriac, what do you think? |
Looks like that restriction was put into practise for m7 cores (hardfaults). If we don't find a better alternative (like not touching anything just scratch registers), we might just use thumb instruction for all cores. I can't think of anything better at the moment. You guys? |
Was toying around with this a while back, here's a small thumb trampoline that avoids undefined instructions: 0xa002 // add r0, pc, #8
0xc803 // ldm r0, {r0, r1}
0x4708 // bx r1
0x0000 // make sure context and callback are aligned
context
callback EDIT: I realized the above was a 1-argument thunk. The 0xa002 // add r0, pc, #8
0xc80f // ldm r0, {r0, r1, r2, r3}
0x4718 // bx r3
0x0000 // make sure context and callback are aligned
context
instance
callback
trampoline It's kinda sad to see the |
This solution looks great to me. I don't think we can do shorter. Because it use only thumb instruction set, we could also use it for CM0/CM0+. |
@meriac @AlessandroA : if you have something against this, speak now :) |
The only reason why I could imagine a different behavior between the cores is because of this condition not passing (from
Where The following instructions would be an alternative to what @geky proposed: add r0, pc, #8
ldm r0, {r0, r1, r2, pc} You don't need to take |
The above code snippet looks good, saves 4 bytes :) @AlessandroA thanks for looking at this. Same footprint, but we might want unified version. @svastm Can you test locally please and rebase? |
Thanks @AlessandroA! LGTM. |
- Add support of cortex-M7 for cthunk. - Change the cthunk trampoline implementation to safer and quicker solutions: * thumb2, the behaviour was undefined. new implementation use now 2 instructions * thumb, The new implementation use 3 instructions instead of 6.
I rebase with the new implementations thanks to @geky and @AlessandroA. I kept the geky solution for thumb implementation because the ldm thumb instruction can use only low register. For Cortex-A9 i switched to thumb2 solution but I don't have a Cortex-A9 so I can't test it. |
Tested locally with the Cortex-A9 RZ_A1H, looks good to me: 👍
|
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
Outputmbed Build Number: 850 All builds and test passed! |
Ports for Upcoming Targets 2669: Added u-blox C029 target ARMmbed/mbed-os#2669 2707: [EFM32] Add IAR support for remaining Silicon Labs targets ARMmbed/mbed-os#2707 2819: MultiTech xDot platform support - 09.26.2016 ARMmbed/mbed-os#2819 2827: include MultiTech xDot in mbed 5 releases ARMmbed/mbed-os#2827 Fixes and Changes 2522: Add CThunk for CM7 ARMmbed/mbed-os#2522 2518: Enable uvisor on Beetle ARMmbed/mbed-os#2518 2571: STM32F7 - Add asynchronous serial ARMmbed/mbed-os#2571 2616: STM32F3xx - Add Serial Flow Control pins + enable it ARMmbed/mbed-os#2616 2619: NUCLEO_L152RE - Add Serial Flow Control ARMmbed/mbed-os#2619 2620: NUCLEO_F429ZI - Add SERIAL_FC macro ARMmbed/mbed-os#2620 2666: [EFM32] Microsecond ticker optimization ARMmbed/mbed-os#2666 2681: STM32F0xx - Add support of ADC internal channels ARMmbed/mbed-os#2681 2687: [NRF5] Add fs_data symbol in data secton for gcc ARMmbed/mbed-os#2687 2696: Add device_has to all nrf51 devices ARMmbed/mbed-os#2696 2703: TARGET_NRF5: Changed 'serial_baud' implementation to support special baud rates. ARMmbed/mbed-os#2703 2704: DISCO_L476VG: add SPI nicknames ARMmbed/mbed-os#2704 2723: KSDK serial_api.c: Fix assertion error for ParityEven ARMmbed/mbed-os#2723 2463: [STM32L0] Add asynchronous serial ARMmbed/mbed-os#2463 2572: Fix STM32F407VG target name and LPC11U6X linker errors ARMmbed/mbed-os#2572 2698: DELTA_DFBM_NQ620 target ARMmbed/mbed-os#2698 2542: Dev spi asynch stm32f4 ARMmbed/mbed-os#2542 2650: STM32F3 - Add low power timer ARMmbed/mbed-os#2650 2415: [STM32F0] Add asynchronous serial ARMmbed/mbed-os#2415 2585: Added support for ADC only pins in LPC43xx ARMmbed/mbed-os#2585 2622: [STM32F4] Add asynchronous I2C ARMmbed/mbed-os#2622 2719: Updated ARM linker scripts for Kinetis platforms that use SDK 2.0 ARMmbed/mbed-os#2719 2728: Added ethernet and enabled IPV4 feature for the EVK-ODIN-W2/C029 target ARMmbed/mbed-os#2728 2747: [LPC11U68] Fix pin interrupt select offset ARMmbed/mbed-os#2747 2751: STM32L0xx - Add Serial Flow Control ARMmbed/mbed-os#2751 2753: [NUCLEO_F767ZI] Add CAN capability ARMmbed/mbed-os#2753 2759: STM32F0 - Add low power timer ARMmbed/mbed-os#2759 2763: STM32L1 - Add low power timer ARMmbed/mbed-os#2763 2764: STM32L4 - Add low power timer ARMmbed/mbed-os#2764 2771: STM32L4 - Update deepsleep implementation ARMmbed/mbed-os#2771 2775: Update KSDK SDHC driver for K64F & K66F ARMmbed/mbed-os#2775 2792: [NUCLEO_F303ZE] MBED-OS5 capability ARMmbed/mbed-os#2792 2762: STM32L0 - Add low power timer ARMmbed/mbed-os#2762 2761: STM32F7 - Add low power timer ARMmbed/mbed-os#2761
The asynchronous versions of the communication interfaces (serial, i2c and spi) need the CThunk class which is not yet implemented for cortex-M7.
My first idea was to use the same OP code than CM3 and CM4,
ldm.w pc,{r0,r1,r2,pc}
, because they use ARMv7-M and thumb2 like the CM7. But this OP code give me an hard fault and I don't understand why.I poorly used the code from CM0, CM0+ which looks cleaner but a bit longer. Then I was able to run the following test code on ARM and IAR but it still fail on GCC. I tried with a NUCLEO_F746ZG and a DISCO_F746NG.
I'm a bit stuck there and i can't find something in the ARMv7-M manual which say to not use the
ldm.w pc,{r0,r1,r2,pc}
.Someone has already looked at this ?