Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/machine/machine_rp2.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func machineInit() {

// Peripheral clocks should now all be running
unresetBlockWait(RESETS_RESET_Msk)

// DBGPAUSE pauses the timer when a debugger is connected. This prevents
// sleep functions from ever returning, so disable it.
timer.setDbgPause(false)
}

//go:linkname ticks runtime.machineTicks
Expand Down
12 changes: 12 additions & 0 deletions src/machine/machine_rp2_timer.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,15 @@ func (tmr *timerType) lightSleep(us uint64) {
// Disable interrupt
intr.Disable()
}

// setDbgPause sets whether this timer is paused when a debugger is connected.
func (tmr *timerType) setDbgPause(enable bool) {
const bitPos = 1
const bitMask = 0b11
val := uint32(0b00)
if enable {
// Disable timer when debugger is connected to either core.
val = 0b11
}
tmr.dbgPause.ReplaceBits(val, bitMask, bitPos)
}
29 changes: 21 additions & 8 deletions src/runtime/runtime_rp2.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
)

const numCPU = 2
const numSpinlocks = 32

// machineTicks is provided by package machine.
func machineTicks() uint64
Expand Down Expand Up @@ -291,12 +292,19 @@ func coreStackTop(core uint32) uintptr {

// These spinlocks are needed by the runtime.
var (
printLock = spinLock{id: 0}
schedulerLock = spinLock{id: 1}
atomicsLock = spinLock{id: 2}
futexLock = spinLock{id: 3}
printLock = spinLock{id: 20}
schedulerLock = spinLock{id: 21}
atomicsLock = spinLock{id: 22}
futexLock = spinLock{id: 23}
)

func resetSpinLocks() {
for i := uint8(0); i < numSpinlocks; i++ {
l := &spinLock{id: i}
l.spinlock().Set(0)
}
}

// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
type spinLock struct {
id uint8
Expand All @@ -311,15 +319,13 @@ func (l *spinLock) Lock() {
// Wait for the lock to be available.
spinlock := l.spinlock()
for spinlock.Get() == 0 {
// TODO: use wfe and send an event when unlocking so the CPU can go to
// sleep while waiting for the lock.
// Unfortunately when doing that, time.Sleep() seems to hang somewhere.
// This needs some debugging to figure out.
arm.Asm("wfe")
}
}

func (l *spinLock) Unlock() {
l.spinlock().Set(0)
arm.Asm("sev")
}

// Wait until a signal is received, indicating that it can resume from the
Expand Down Expand Up @@ -359,9 +365,16 @@ func init() {
machine.InitSerial()
}

func prerun() {
// Reset spinlocks before the full machineInit() so the scheduler doesn't
// hang waiting for schedulerLock after a soft reset.
resetSpinLocks()
}

//export Reset_Handler
func main() {
preinit()
prerun()
run()
exit(0)
}
Loading