diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index 5b315542..b7a3774b 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -14,8 +14,6 @@ import ( type timeUnit int64 -const tickMicros = 32768 // RTC runs at 32.768kHz - //go:extern _sbss var _sbss unsafe.Pointer @@ -82,3 +80,26 @@ func putchar(c byte) { } const asyncScheduler = false + +func ticks() timeUnit { + // Combining the low bits and the high bits yields a time span of over 270 + // years without counter rollover. + highBits := sifive.CLINT.MTIMEH.Get() + for { + lowBits := sifive.CLINT.MTIME.Get() + newHighBits := sifive.CLINT.MTIMEH.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 + } +} + +func sleepTicks(d timeUnit) { + target := ticks() + d + for ticks() < target { + } +} \ No newline at end of file diff --git a/src/runtime/runtime_fe310_baremetal.go b/src/runtime/runtime_fe310_baremetal.go index 7c9fcf7f..e04560c4 100644 --- a/src/runtime/runtime_fe310_baremetal.go +++ b/src/runtime/runtime_fe310_baremetal.go @@ -4,36 +4,13 @@ package runtime import ( "device/riscv" - "device/sifive" ) +const tickMicros = 32768 // RTC clock runs at 32.768kHz + func abort() { // lock up forever for { 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 c5c38081..132515e7 100644 --- a/src/runtime/runtime_fe310_qemu.go +++ b/src/runtime/runtime_fe310_qemu.go @@ -7,6 +7,8 @@ import ( "unsafe" ) +const tickMicros = 100 // CLINT.MTIME increments every 100ns + // Special memory-mapped device to exit tests, created by SiFive. var testExit = (*volatile.Register32)(unsafe.Pointer(uintptr(0x100000))) @@ -16,13 +18,3 @@ 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 -}