From 78f0a56e5836ffaa6228c39793f68281c57f443a Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 4 Nov 2025 11:12:01 +0000 Subject: [PATCH 1/3] [libc] Enable the FPU in Arm startup code This patch enables the FPU in Arm startup code, which is required to run tests on Arm configurations with hardware floating-point support. --- libc/startup/baremetal/arm/start.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) 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(__data_size)); From fd44ca52d40c7c9a4a418adcfb33293bb40b84a8 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Wed, 5 Nov 2025 15:29:55 +0000 Subject: [PATCH 2/3] Move the ISB barrier --- libc/startup/baremetal/arm/start.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp index a88861929a23f..da8d8a2ab6108 100644 --- a/libc/startup/baremetal/arm/start.cpp +++ b/libc/startup/baremetal/arm/start.cpp @@ -144,12 +144,12 @@ namespace LIBC_NAMESPACE_DECL { uint32_t cpacr = __arm_rsr("p15:0:c1:c0:2"); cpacr |= (0xF << 20); __arm_wsr("p15:0:c1:c0:2", cpacr); + __isb(0xF); // 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 From 8e08d5f41b8a9d2c206e5593812552fda47c541b Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Wed, 5 Nov 2025 16:36:52 +0000 Subject: [PATCH 3/3] Added links to references --- libc/startup/baremetal/arm/start.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp index da8d8a2ab6108..4740067722022 100644 --- a/libc/startup/baremetal/arm/start.cpp +++ b/libc/startup/baremetal/arm/start.cpp @@ -134,12 +134,16 @@ namespace LIBC_NAMESPACE_DECL { #ifdef __ARM_FP // Enable FPU #if __ARM_ARCH_PROFILE == 'M' + // Based on + // https://developer.arm.com/documentation/dui0646/c/Cortex-M7-Peripherals/Floating-Point-Unit/Enabling-the-FPU // 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' + // Based on + // https://developer.arm.com/documentation/dui0472/m/Compiler-Coding-Practices/Enabling-NEON-and-FPU-for-bare-metal // Set CPACR cp10 and cp11 uint32_t cpacr = __arm_rsr("p15:0:c1:c0:2"); cpacr |= (0xF << 20);