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
Этот коммит содержится в:
Ayke van Laethem 2019-12-25 17:48:23 +01:00 коммит произвёл Ron Evans
родитель 14474e7099
коммит 184827e4d8
3 изменённых файлов: 37 добавлений и 23 удалений

Просмотреть файл

@ -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
}