riscv: support sleeping in QEMU

QEMU doesn't support the RTC peripheral yet so work around it for now.

This makes the following command work:

    tinygo run -target=hifive1-qemu ./testdata/coroutines.go
This commit is contained in:
Ayke van Laethem
2019-12-25 17:48:23 +01:00
committed by Ron Evans
parent 14474e7099
commit 184827e4d8
3 changed files with 37 additions and 23 deletions
+25
View File
@@ -4,6 +4,7 @@ package runtime
import (
"device/riscv"
"device/sifive"
)
func abort() {
@@ -12,3 +13,27 @@ func abort() {
riscv.Asm("wfi")
}
}
func ticks() timeUnit {
// Combining the low bits and the high bits yields a time span of over 270
// years without counter rollover.
highBits := sifive.RTC.RTCHI.Get()
for {
lowBits := sifive.RTC.RTCLO.Get()
newHighBits := sifive.RTC.RTCHI.Get()
if newHighBits == highBits {
// High bits stayed the same.
println("bits:", highBits, lowBits)
return timeUnit(lowBits) | (timeUnit(highBits) << 32)
}
// Retry, because there was a rollover in the low bits (happening every
// 1.5 days).
highBits = newHighBits
}
}
func sleepTicks(d timeUnit) {
target := ticks() + d
for ticks() < target {
}
}