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.
Этот коммит содержится в:
Ayke van Laethem 2021-04-24 01:52:04 +02:00 коммит произвёл Ron Evans
родитель 4eac212695
коммит f79e66ac2e
5 изменённых файлов: 20 добавлений и 12 удалений

Просмотреть файл

@ -26,12 +26,21 @@ type SCB_Type struct {
SHPR2 volatile.Register32 // 0xD1C: System Handler Priority Register 2 SHPR2 volatile.Register32 // 0xD1C: System Handler Priority Register 2
SHPR3 volatile.Register32 // 0xD20: System Handler Priority Register 3 SHPR3 volatile.Register32 // 0xD20: System Handler Priority Register 3
// the following are only applicable for Cortex-M3/M33/M4/M7 // the following are only applicable for Cortex-M3/M33/M4/M7
SHCSR volatile.Register32 // 0xD24: System Handler Control and State Register SHCSR volatile.Register32 // 0xD24: System Handler Control and State Register
CFSR volatile.Register32 // 0xD28: Configurable Fault Status Register CFSR volatile.Register32 // 0xD28: Configurable Fault Status Register
HFSR volatile.Register32 // 0xD2C: HardFault Status Register HFSR volatile.Register32 // 0xD2C: HardFault Status Register
DFSR volatile.Register32 // 0xD30: Debug Fault Status Register DFSR volatile.Register32 // 0xD30: Debug Fault Status Register
MMFAR volatile.Register32 // 0xD34: MemManage Fault Address Register MMFAR volatile.Register32 // 0xD34: MemManage Fault Address Register
BFAR volatile.Register32 // 0xD38: BusFault 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))) var SCB = (*SCB_Type)(unsafe.Pointer(uintptr(SCB_BASE)))

Просмотреть файл

@ -16,6 +16,7 @@ func postinit() {}
//export Reset_Handler //export Reset_Handler
func main() { func main() {
arm.SCB.CPACR.Set(0) // disable FPU if it is enabled
preinit() preinit()
run() run()
abort() abort()

Просмотреть файл

@ -102,11 +102,6 @@ func initSystem() {
func initPeripherals() { 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 enableTimerClocks() // activate GPT/PIT clock gates
initSysTick() // enable SysTick initSysTick() // enable SysTick
initRTC() // enable real-time clock initRTC() // enable real-time clock

Просмотреть файл

@ -3,6 +3,7 @@
package runtime package runtime
import ( import (
"device/arm"
"device/nrf" "device/nrf"
"machine" "machine"
"runtime/interrupt" "runtime/interrupt"
@ -18,6 +19,9 @@ func postinit() {}
//export Reset_Handler //export Reset_Handler
func main() { func main() {
if nrf.FPUPresent {
arm.SCB.CPACR.Set(0) // disable FPU if it is enabled
}
systemInit() systemInit()
preinit() preinit()
run() run()

Просмотреть файл

@ -75,7 +75,6 @@ func initSystem() {
nxp.SIM.SCGC3.Set(nxp.SIM_SCGC3_ADC1 | nxp.SIM_SCGC3_FTM2 | nxp.SIM_SCGC3_FTM3) 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.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.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) nxp.LMEM.PCCCR.Set(0x85000003)
// release I/O pins hold, if we woke up from VLLS mode // release I/O pins hold, if we woke up from VLLS mode