mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 12:33:42 +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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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