mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-22 13:29:01 +00:00
runtime/rp2: handle RP2350 shared FIFO IRQ for GC (#5482)
* runtime/rp2: handle RP2350 shared FIFO IRQ for GC --------- Co-authored-by: rdon <you@example.com>
This commit is contained in:
@@ -8,7 +8,6 @@ import (
|
|||||||
"internal/task"
|
"internal/task"
|
||||||
"machine"
|
"machine"
|
||||||
_ "machine/usb/cdc"
|
_ "machine/usb/cdc"
|
||||||
"runtime/interrupt"
|
|
||||||
"runtime/volatile"
|
"runtime/volatile"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -140,14 +139,7 @@ func startSecondaryCores() {
|
|||||||
// Enable the FIFO interrupt for the GC stop the world phase.
|
// Enable the FIFO interrupt for the GC stop the world phase.
|
||||||
// We can only do this after we don't need the FIFO anymore for starting the
|
// We can only do this after we don't need the FIFO anymore for starting the
|
||||||
// second core.
|
// second core.
|
||||||
intr := interrupt.New(sioIrqFifoProc0, func(intr interrupt.Interrupt) {
|
enableSIOFifoInterruptCore0()
|
||||||
switch rp.SIO.FIFO_RD.Get() {
|
|
||||||
case 1:
|
|
||||||
gcInterruptHandler(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
intr.Enable()
|
|
||||||
intr.SetPriority(0xff)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var core1StartSequence = [...]uint32{
|
var core1StartSequence = [...]uint32{
|
||||||
@@ -174,14 +166,7 @@ func runCore1() {
|
|||||||
// the GC.
|
// the GC.
|
||||||
// Use the lowest possible priority (highest priority value), so that other
|
// Use the lowest possible priority (highest priority value), so that other
|
||||||
// interrupts can still happen while the GC is running.
|
// interrupts can still happen while the GC is running.
|
||||||
intr := interrupt.New(sioIrqFifoProc1, func(intr interrupt.Interrupt) {
|
enableSIOFifoInterruptCore1()
|
||||||
switch rp.SIO.FIFO_RD.Get() {
|
|
||||||
case 1:
|
|
||||||
gcInterruptHandler(1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
intr.Enable()
|
|
||||||
intr.SetPriority(0xff)
|
|
||||||
|
|
||||||
// Now start running the scheduler on this core.
|
// Now start running the scheduler on this core.
|
||||||
schedulerLock.Lock()
|
schedulerLock.Lock()
|
||||||
|
|||||||
@@ -4,9 +4,39 @@ package runtime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"device/rp"
|
"device/rp"
|
||||||
|
"runtime/interrupt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_PROC0
|
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_PROC0
|
||||||
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_PROC1
|
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_PROC1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// On RP2040, each core has its own SIO FIFO IRQ. Core0 enables
|
||||||
|
// IRQ_SIO_IRQ_PROC0 and Core1 enables IRQ_SIO_IRQ_PROC1, so each handler can
|
||||||
|
// use a fixed core ID.
|
||||||
|
func enableSIOFifoInterruptCore0() {
|
||||||
|
intr := interrupt.New(sioIrqFifoProc0, handleSIOFifoInterruptCore0)
|
||||||
|
intr.Enable()
|
||||||
|
intr.SetPriority(0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableSIOFifoInterruptCore1() {
|
||||||
|
intr := interrupt.New(sioIrqFifoProc1, handleSIOFifoInterruptCore1)
|
||||||
|
intr.Enable()
|
||||||
|
intr.SetPriority(0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSIOFifoInterruptCore0(intr interrupt.Interrupt) {
|
||||||
|
switch rp.SIO.FIFO_RD.Get() {
|
||||||
|
case 1:
|
||||||
|
gcInterruptHandler(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSIOFifoInterruptCore1(intr interrupt.Interrupt) {
|
||||||
|
switch rp.SIO.FIFO_RD.Get() {
|
||||||
|
case 1:
|
||||||
|
gcInterruptHandler(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package runtime
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"device/rp"
|
"device/rp"
|
||||||
|
"runtime/interrupt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -14,3 +15,25 @@ const (
|
|||||||
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_FIFO
|
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_FIFO
|
||||||
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_FIFO
|
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_FIFO
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var sioFifoInterrupt = interrupt.New(sioIrqFifoProc0, handleSIOFifoInterrupt)
|
||||||
|
|
||||||
|
// On RP2350 both cores share IRQ_SIO_IRQ_FIFO, but the NVIC enable and
|
||||||
|
// priority state is per-core. Each core must enable the shared IRQ on
|
||||||
|
// its own NVIC, so both Core0 and Core1 call Enable()/SetPriority().
|
||||||
|
func enableSIOFifoInterruptCore0() {
|
||||||
|
sioFifoInterrupt.Enable()
|
||||||
|
sioFifoInterrupt.SetPriority(0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableSIOFifoInterruptCore1() {
|
||||||
|
sioFifoInterrupt.Enable()
|
||||||
|
sioFifoInterrupt.SetPriority(0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSIOFifoInterrupt(intr interrupt.Interrupt) {
|
||||||
|
switch rp.SIO.FIFO_RD.Get() {
|
||||||
|
case 1:
|
||||||
|
gcInterruptHandler(currentCPU())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user