-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[libc] Enable the FPU in Arm startup code #166349
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
Conversation
This patch enables the FPU in Arm startup code, which is required to run tests on Arm configurations with hardware floating-point support.
|
@llvm/pr-subscribers-libc Author: Victor Campos (vhscampos) ChangesThis patch enables the FPU in Arm startup code, which is required to run tests on Arm configurations with hardware floating-point support. Full diff: https://github.com/llvm/llvm-project/pull/166349.diff 1 Files Affected:
diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp
index c089a14f5f782..a88861929a23f 100644
--- a/libc/startup/baremetal/arm/start.cpp
+++ b/libc/startup/baremetal/arm/start.cpp
@@ -131,6 +131,28 @@ namespace LIBC_NAMESPACE_DECL {
__arm_wsr("CPSR_c", 0x13); // SVC
#endif
+#ifdef __ARM_FP
+// Enable FPU
+#if __ARM_ARCH_PROFILE == 'M'
+ // Set CPACR cp10 and cp11
+ auto cpacr = (volatile uint32_t *const)0xE000ED88;
+ *cpacr |= (0xF << 20);
+ __dsb(0xF);
+ __isb(0xF);
+#elif __ARM_ARCH_PROFILE == 'A' || __ARM_ARCH_PROFILE == 'R'
+ // Set CPACR cp10 and cp11
+ uint32_t cpacr = __arm_rsr("p15:0:c1:c0:2");
+ cpacr |= (0xF << 20);
+ __arm_wsr("p15:0:c1:c0:2", cpacr);
+ // Set FPEXC.EN
+ uint32_t fpexc;
+ __asm__ __volatile__("vmrs %0, FPEXC" : "=r"(fpexc) : :);
+ fpexc |= (1 << 30);
+ __asm__ __volatile__("vmsr FPEXC, %0" : : "r"(fpexc) :);
+ __isb(0xF);
+#endif
+#endif
+
// Perform the equivalent of scatterloading
LIBC_NAMESPACE::memcpy(__data_start, __data_source,
reinterpret_cast<uintptr_t>(__data_size));
|
| // Set CPACR cp10 and cp11 | ||
| auto cpacr = (volatile uint32_t *const)0xE000ED88; | ||
| *cpacr |= (0xF << 20); | ||
| __dsb(0xF); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this makes sense to me except that I'm not sure why this __dsb is here and not in the A/R branch. I didn't see any ArmARM documentation that mentioned it. Is it deliberately M-only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the M-profile I've based it on this example: https://developer.arm.com/documentation/dui0646/c/Cortex-M7-Peripherals/Floating-Point-Unit/Enabling-the-FPU
For A/R profiles I couldn't find an example as normative.
The best I could find was from this: https://developer.arm.com/documentation/dui0472/m/Compiler-Coding-Practices/Enabling-NEON-and-FPU-for-bare-metal
Although this one doesn't have any sort of barrier: https://developer.arm.com/documentation/ddi0408/g/Programmers-Model/Register-summary/Accessing-the-FPU-registers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the references. I notice that the middle one of your links puts the ISB before attempting to mess with FPEXC, rather than after, which makes sense to me since the VMSR/VMRS pair are themselves (modelled as) MRC/MCR to coprocessor 10 which you've only just enabled. That seems like a reasonable precaution if we're going to include it at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @vhscampos and @statham-arm ! @vhscampos do you mind adding the references for these to the comments for each cases? Thanks,
This patch enables the FPU in Arm startup code, which is required to run tests on Arm configurations with hardware floating-point support.