diff options
author | Ayke van Laethem <[email protected]> | 2020-03-22 20:11:46 +0100 |
---|---|---|
committer | Ron Evans <[email protected]> | 2020-03-26 23:03:55 +0100 |
commit | 980068543a1f9d720d7bb523b00c9818d383e916 (patch) | |
tree | b4e7b0fdb308f656f636b6e241fa11baf54364f9 /src/runtime | |
parent | c4fd19be99c2695f25ac59057adef7a44ad61ad9 (diff) | |
download | tinygo-980068543a1f9d720d7bb523b00c9818d383e916.tar.gz tinygo-980068543a1f9d720d7bb523b00c9818d383e916.zip |
riscv: implement VirtIO target
This allows running RISC-V tests in CI using QEMU, which should help
catch bugs.
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/runtime_fe310.go | 33 | ||||
-rw-r--r-- | src/runtime/runtime_tinygoriscv.go | 38 | ||||
-rw-r--r-- | src/runtime/runtime_tinygoriscv_qemu.go | 63 |
3 files changed, 101 insertions, 33 deletions
diff --git a/src/runtime/runtime_fe310.go b/src/runtime/runtime_fe310.go index 62673ad35..2af409025 100644 --- a/src/runtime/runtime_fe310.go +++ b/src/runtime/runtime_fe310.go @@ -16,21 +16,6 @@ import ( type timeUnit int64 -//go:extern _sbss -var _sbss [0]byte - -//go:extern _ebss -var _ebss [0]byte - -//go:extern _sdata -var _sdata [0]byte - -//go:extern _sidata -var _sidata [0]byte - -//go:extern _edata -var _edata [0]byte - func postinit() {} //go:export main @@ -108,24 +93,6 @@ func initPeripherals() { machine.UART0.Configure(machine.UARTConfig{}) } -func preinit() { - // Initialize .bss: zero-initialized global variables. - ptr := unsafe.Pointer(&_sbss) - for ptr != unsafe.Pointer(&_ebss) { - *(*uint32)(ptr) = 0 - ptr = unsafe.Pointer(uintptr(ptr) + 4) - } - - // Initialize .data: global variables initialized from flash. - src := unsafe.Pointer(&_sidata) - dst := unsafe.Pointer(&_sdata) - for dst != unsafe.Pointer(&_edata) { - *(*uint32)(dst) = *(*uint32)(src) - dst = unsafe.Pointer(uintptr(dst) + 4) - src = unsafe.Pointer(uintptr(src) + 4) - } -} - func putchar(c byte) { machine.UART0.WriteByte(c) } diff --git a/src/runtime/runtime_tinygoriscv.go b/src/runtime/runtime_tinygoriscv.go new file mode 100644 index 000000000..93bf1e45f --- /dev/null +++ b/src/runtime/runtime_tinygoriscv.go @@ -0,0 +1,38 @@ +// +build tinygo.riscv + +package runtime + +import "unsafe" + +//go:extern _sbss +var _sbss [0]byte + +//go:extern _ebss +var _ebss [0]byte + +//go:extern _sdata +var _sdata [0]byte + +//go:extern _sidata +var _sidata [0]byte + +//go:extern _edata +var _edata [0]byte + +func preinit() { + // Initialize .bss: zero-initialized global variables. + ptr := unsafe.Pointer(&_sbss) + for ptr != unsafe.Pointer(&_ebss) { + *(*uint32)(ptr) = 0 + ptr = unsafe.Pointer(uintptr(ptr) + 4) + } + + // Initialize .data: global variables initialized from flash. + src := unsafe.Pointer(&_sidata) + dst := unsafe.Pointer(&_sdata) + for dst != unsafe.Pointer(&_edata) { + *(*uint32)(dst) = *(*uint32)(src) + dst = unsafe.Pointer(uintptr(dst) + 4) + src = unsafe.Pointer(uintptr(src) + 4) + } +} diff --git a/src/runtime/runtime_tinygoriscv_qemu.go b/src/runtime/runtime_tinygoriscv_qemu.go new file mode 100644 index 000000000..74a8fc198 --- /dev/null +++ b/src/runtime/runtime_tinygoriscv_qemu.go @@ -0,0 +1,63 @@ +// +build tinygo.riscv,qemu + +package runtime + +import ( + "device/riscv" + "runtime/volatile" + "unsafe" +) + +// This file implements the VirtIO RISC-V interface implemented in QEMU, which +// is an interface designed for emulation. + +type timeUnit int64 + +const tickMicros = 1 + +var timestamp timeUnit + +func postinit() {} + +//go:export main +func main() { + preinit() + run() + abort() +} + +const asyncScheduler = false + +func sleepTicks(d timeUnit) { + // TODO: actually sleep here for the given time. + timestamp += d +} + +func ticks() timeUnit { + return timestamp +} + +// Memory-mapped I/O as defined by QEMU. +// Source: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c +// Technically this is an implementation detail but hopefully they won't change +// the memory-mapped I/O registers. +var ( + // UART0 output register. + stdoutWrite = (*volatile.Register8)(unsafe.Pointer(uintptr(0x10000000))) + // SiFive test finisher + testFinisher = (*volatile.Register16)(unsafe.Pointer(uintptr(0x100000))) +) + +func putchar(c byte) { + stdoutWrite.Set(uint8(c)) +} + +func abort() { + // Make sure the QEMU process exits. + testFinisher.Set(0x5555) // FINISHER_PASS + + // Lock up forever (as a fallback). + for { + riscv.Asm("wfi") + } +} |