From f79e66ac2e66a5338ec3ce3c4c992567b07c4959 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 24 Apr 2021 01:52:04 +0200 Subject: [PATCH] cortexm: disable FPU on Cortex-M4 On some boards the FPU is already enabled on startup, probably as part of the bootloader. On other chips it was enabled as part of the runtime startup code. In all these cases, enabling the FPU is currently unsupported: the automatic stack sizing of goroutines assumes that the processor won't need to reserve space for FPU registers. Enabling the FPU therefore can lead to a stack overflow. This commit either removes the code that enables the FPU, or simply disables it in startup code. A future change should fully enable the FPU so that operations on float32 can be performed by the FPU instead of in software, greatly speeding up such code. --- src/device/arm/scb.go | 21 +++++++++++++++------ src/runtime/runtime_atsamd51.go | 1 + src/runtime/runtime_mimxrt1062.go | 5 ----- src/runtime/runtime_nrf.go | 4 ++++ src/runtime/runtime_nxpmk66f18.go | 1 - 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/device/arm/scb.go b/src/device/arm/scb.go index 5ecb23c9..c3d782e0 100644 --- a/src/device/arm/scb.go +++ b/src/device/arm/scb.go @@ -26,12 +26,21 @@ type SCB_Type struct { SHPR2 volatile.Register32 // 0xD1C: System Handler Priority Register 2 SHPR3 volatile.Register32 // 0xD20: System Handler Priority Register 3 // the following are only applicable for Cortex-M3/M33/M4/M7 - SHCSR volatile.Register32 // 0xD24: System Handler Control and State Register - CFSR volatile.Register32 // 0xD28: Configurable Fault Status Register - HFSR volatile.Register32 // 0xD2C: HardFault Status Register - DFSR volatile.Register32 // 0xD30: Debug Fault Status Register - MMFAR volatile.Register32 // 0xD34: MemManage Fault Address Register - BFAR volatile.Register32 // 0xD38: BusFault Address Register + SHCSR volatile.Register32 // 0xD24: System Handler Control and State Register + CFSR volatile.Register32 // 0xD28: Configurable Fault Status Register + HFSR volatile.Register32 // 0xD2C: HardFault Status Register + DFSR volatile.Register32 // 0xD30: Debug Fault Status Register + MMFAR volatile.Register32 // 0xD34: MemManage Fault Address Register + BFAR volatile.Register32 // 0xD38: BusFault Address Register + AFSR volatile.Register32 // 0xD3C: Auxiliary Fault Status Register + PFR [2]volatile.Register32 // 0xD40: Processor Feature Register + DFR volatile.Register32 // 0xD48: Debug Feature Register + ADR volatile.Register32 // 0xD4C: Auxiliary Feature Register + MMFR [4]volatile.Register32 // 0xD50: Memory Model Feature Register + ISAR [5]volatile.Register32 // 0xD60: Instruction Set Attributes Register + _ [5]uint32 // reserved + CPACR volatile.Register32 // 0xD88: Coprocessor Access Control Register + } var SCB = (*SCB_Type)(unsafe.Pointer(uintptr(SCB_BASE))) diff --git a/src/runtime/runtime_atsamd51.go b/src/runtime/runtime_atsamd51.go index c21324ea..8f3b2f98 100644 --- a/src/runtime/runtime_atsamd51.go +++ b/src/runtime/runtime_atsamd51.go @@ -16,6 +16,7 @@ func postinit() {} //export Reset_Handler func main() { + arm.SCB.CPACR.Set(0) // disable FPU if it is enabled preinit() run() abort() diff --git a/src/runtime/runtime_mimxrt1062.go b/src/runtime/runtime_mimxrt1062.go index 3d0d5747..7fbd0d9e 100644 --- a/src/runtime/runtime_mimxrt1062.go +++ b/src/runtime/runtime_mimxrt1062.go @@ -102,11 +102,6 @@ func initSystem() { func initPeripherals() { - // enable FPU - set CP10, CP11 full access - nxp.SystemControl.CPACR.SetBits( - ((nxp.SCB_CPACR_CP10_CP10_3 << nxp.SCB_CPACR_CP10_Pos) & nxp.SCB_CPACR_CP10_Msk) | - ((nxp.SCB_CPACR_CP11_CP11_3 << nxp.SCB_CPACR_CP11_Pos) & nxp.SCB_CPACR_CP11_Msk)) - enableTimerClocks() // activate GPT/PIT clock gates initSysTick() // enable SysTick initRTC() // enable real-time clock diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index 20f81f1a..fcab3646 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -3,6 +3,7 @@ package runtime import ( + "device/arm" "device/nrf" "machine" "runtime/interrupt" @@ -18,6 +19,9 @@ func postinit() {} //export Reset_Handler func main() { + if nrf.FPUPresent { + arm.SCB.CPACR.Set(0) // disable FPU if it is enabled + } systemInit() preinit() run() diff --git a/src/runtime/runtime_nxpmk66f18.go b/src/runtime/runtime_nxpmk66f18.go index a46aa11e..cff830d2 100644 --- a/src/runtime/runtime_nxpmk66f18.go +++ b/src/runtime/runtime_nxpmk66f18.go @@ -75,7 +75,6 @@ func initSystem() { nxp.SIM.SCGC3.Set(nxp.SIM_SCGC3_ADC1 | nxp.SIM_SCGC3_FTM2 | nxp.SIM_SCGC3_FTM3) nxp.SIM.SCGC5.Set(0x00043F82) // clocks active to all GPIO nxp.SIM.SCGC6.Set(nxp.SIM_SCGC6_RTC | nxp.SIM_SCGC6_FTM0 | nxp.SIM_SCGC6_FTM1 | nxp.SIM_SCGC6_ADC0 | nxp.SIM_SCGC6_FTF) - nxp.SystemControl.CPACR.Set(0x00F00000) nxp.LMEM.PCCCR.Set(0x85000003) // release I/O pins hold, if we woke up from VLLS mode