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:
rdon(あーるどん)
2026-07-03 17:21:29 +09:00
committed by GitHub
parent 30355cec9f
commit bf80e9b446
3 changed files with 55 additions and 17 deletions
+2 -17
View File
@@ -8,7 +8,6 @@ import (
"internal/task"
"machine"
_ "machine/usb/cdc"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
)
@@ -140,14 +139,7 @@ func startSecondaryCores() {
// 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
// second core.
intr := interrupt.New(sioIrqFifoProc0, func(intr interrupt.Interrupt) {
switch rp.SIO.FIFO_RD.Get() {
case 1:
gcInterruptHandler(0)
}
})
intr.Enable()
intr.SetPriority(0xff)
enableSIOFifoInterruptCore0()
}
var core1StartSequence = [...]uint32{
@@ -174,14 +166,7 @@ func runCore1() {
// the GC.
// Use the lowest possible priority (highest priority value), so that other
// interrupts can still happen while the GC is running.
intr := interrupt.New(sioIrqFifoProc1, func(intr interrupt.Interrupt) {
switch rp.SIO.FIFO_RD.Get() {
case 1:
gcInterruptHandler(1)
}
})
intr.Enable()
intr.SetPriority(0xff)
enableSIOFifoInterruptCore1()
// Now start running the scheduler on this core.
schedulerLock.Lock()
+30
View File
@@ -4,9 +4,39 @@ package runtime
import (
"device/rp"
"runtime/interrupt"
)
const (
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_PROC0
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)
}
}
+23
View File
@@ -4,6 +4,7 @@ package runtime
import (
"device/rp"
"runtime/interrupt"
)
const (
@@ -14,3 +15,25 @@ const (
sioIrqFifoProc0 = 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())
}
}