diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index cef0efba..5b315542 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -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 { - } -} diff --git a/src/runtime/runtime_fe310_baremetal.go b/src/runtime/runtime_fe310_baremetal.go index 229615da..7c9fcf7f 100644 --- a/src/runtime/runtime_fe310_baremetal.go +++ b/src/runtime/runtime_fe310_baremetal.go @@ -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 { + } +} diff --git a/src/runtime/runtime_fe310_qemu.go b/src/runtime/runtime_fe310_qemu.go index bf92ee27..c5c38081 100644 --- a/src/runtime/runtime_fe310_qemu.go +++ b/src/runtime/runtime_fe310_qemu.go @@ -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 +}