
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.
140 строки
3,2 КиБ
Go
140 строки
3,2 КиБ
Go
// +build mimxrt1062
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"device/arm"
|
|
"device/nxp"
|
|
"machine"
|
|
"math/bits"
|
|
"unsafe"
|
|
)
|
|
|
|
const asyncScheduler = false
|
|
|
|
//go:extern _svectors
|
|
var _svectors [0]byte
|
|
|
|
//go:extern _flexram_cfg
|
|
var _flexram_cfg [0]byte
|
|
|
|
func postinit() {}
|
|
|
|
//export Reset_Handler
|
|
func main() {
|
|
|
|
// disable interrupts
|
|
irq := arm.DisableInterrupts()
|
|
|
|
// initialize FPU and VTOR, reset watchdogs
|
|
initSystem()
|
|
|
|
// configure core and peripheral clocks/PLLs/PFDs
|
|
initClocks()
|
|
|
|
// copy data/bss sections from flash to RAM
|
|
preinit()
|
|
|
|
// initialize cache and MPU
|
|
initCache()
|
|
|
|
// enable SysTick, GPIO, and peripherals
|
|
initPeripherals()
|
|
|
|
// reenable interrupts
|
|
arm.EnableInterrupts(irq)
|
|
|
|
run()
|
|
abort()
|
|
}
|
|
|
|
func getRamSizeConfig(itcmKB, dtcmKB uint32) uint32 {
|
|
const minKB, disabled = uint32(4), uint32(0)
|
|
if itcmKB < minKB {
|
|
itcmKB = disabled
|
|
}
|
|
if dtcmKB < minKB {
|
|
dtcmKB = disabled
|
|
}
|
|
itcmKB = uint32(bits.Len(uint(itcmKB))) << nxp.IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_Pos
|
|
dtcmKB = uint32(bits.Len(uint(dtcmKB))) << nxp.IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_Pos
|
|
return (itcmKB & nxp.IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_Msk) |
|
|
(dtcmKB & nxp.IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_Msk)
|
|
}
|
|
|
|
func initSystem() {
|
|
|
|
// configure SRAM capacity (512K for both ITCM and DTCM)
|
|
ramc := uintptr(unsafe.Pointer(&_flexram_cfg))
|
|
nxp.IOMUXC_GPR.GPR17.Set(uint32(ramc))
|
|
nxp.IOMUXC_GPR.GPR16.Set(0x00200007)
|
|
nxp.IOMUXC_GPR.GPR14.Set(getRamSizeConfig(512, 512))
|
|
|
|
// from Teensyduino
|
|
nxp.PMU.MISC0_SET.Set(nxp.PMU_MISC0_REFTOP_SELFBIASOFF)
|
|
|
|
// install vector table (TODO: initialize interrupt/exception table?)
|
|
vtor := uintptr(unsafe.Pointer(&_svectors))
|
|
nxp.SystemControl.VTOR.Set(uint32(vtor))
|
|
|
|
const wdogUpdateKey = 0xD928C520
|
|
|
|
// disable watchdog powerdown counter
|
|
nxp.WDOG1.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk)
|
|
nxp.WDOG2.WMCR.ClearBits(nxp.WDOG_WMCR_PDE_Msk)
|
|
|
|
// disable watchdog
|
|
if nxp.WDOG1.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) {
|
|
nxp.WDOG1.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk)
|
|
}
|
|
if nxp.WDOG2.WCR.HasBits(nxp.WDOG_WCR_WDE_Msk) {
|
|
nxp.WDOG2.WCR.ClearBits(nxp.WDOG_WCR_WDE_Msk)
|
|
}
|
|
if nxp.RTWDOG.CS.HasBits(nxp.RTWDOG_CS_CMD32EN_Msk) {
|
|
nxp.RTWDOG.CNT.Set(wdogUpdateKey)
|
|
} else {
|
|
nxp.RTWDOG.CNT.Set((wdogUpdateKey >> 0) & 0xFFFF)
|
|
nxp.RTWDOG.CNT.Set((wdogUpdateKey >> 16) & 0xFFFF)
|
|
}
|
|
nxp.RTWDOG.TOVAL.Set(0xFFFF)
|
|
nxp.RTWDOG.CS.Set((nxp.RTWDOG.CS.Get() & ^uint32(nxp.RTWDOG_CS_EN_Msk)) | nxp.RTWDOG_CS_UPDATE_Msk)
|
|
}
|
|
|
|
func initPeripherals() {
|
|
|
|
enableTimerClocks() // activate GPT/PIT clock gates
|
|
initSysTick() // enable SysTick
|
|
initRTC() // enable real-time clock
|
|
|
|
enablePinClocks() // activate IOMUXC(_GPR)/GPIO clock gates
|
|
initPins() // configure GPIO
|
|
|
|
enablePeripheralClocks() // activate peripheral clock gates
|
|
initUART() // configure UART (initialized first for debugging)
|
|
}
|
|
|
|
func initPins() {
|
|
// use fast GPIO for all pins (GPIO6-9)
|
|
nxp.IOMUXC_GPR.GPR26.Set(0xFFFFFFFF)
|
|
nxp.IOMUXC_GPR.GPR27.Set(0xFFFFFFFF)
|
|
nxp.IOMUXC_GPR.GPR28.Set(0xFFFFFFFF)
|
|
nxp.IOMUXC_GPR.GPR29.Set(0xFFFFFFFF)
|
|
}
|
|
|
|
func initUART() {
|
|
machine.UART1.Configure(machine.UARTConfig{})
|
|
}
|
|
|
|
func putchar(c byte) {
|
|
machine.UART1.WriteByte(c)
|
|
}
|
|
|
|
func abort() {
|
|
for {
|
|
arm.Asm("wfe")
|
|
}
|
|
}
|
|
|
|
func waitForEvents() {
|
|
arm.Asm("wfe")
|
|
}
|