mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-12 06:53:40 +00:00
riscv: implement VirtIO target
This allows running RISC-V tests in CI using QEMU, which should help catch bugs.
This commit is contained in:
committed by
Ron Evans
parent
c4fd19be99
commit
980068543a
@@ -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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user