mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 03:27:48 +00:00
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:
committed by
Ron Evans
parent
14474e7099
commit
184827e4d8
@@ -81,27 +81,4 @@ func putchar(c byte) {
|
||||
machine.UART0.WriteByte(c)
|
||||
}
|
||||
|
||||
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.
|
||||
return timeUnit(lowBits) | (timeUnit(highBits) << 32)
|
||||
}
|
||||
// Retry, because there was a rollover in the low bits (happening every
|
||||
// 1.5 days).
|
||||
highBits = newHighBits
|
||||
}
|
||||
}
|
||||
|
||||
const asyncScheduler = false
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
target := ticks() + d
|
||||
for ticks() < target {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,19 @@ import (
|
||||
// Special memory-mapped device to exit tests, created by SiFive.
|
||||
var testExit = (*volatile.Register32)(unsafe.Pointer(uintptr(0x100000)))
|
||||
|
||||
var timestamp timeUnit
|
||||
|
||||
func abort() {
|
||||
// Signal a successful exit.
|
||||
testExit.Set(0x5555)
|
||||
}
|
||||
|
||||
func ticks() timeUnit {
|
||||
return timestamp
|
||||
}
|
||||
|
||||
func sleepTicks(d timeUnit) {
|
||||
// Note: QEMU doesn't seem to support the RTC peripheral at the time of
|
||||
// writing so just simulate sleeping here.
|
||||
timestamp += d
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user