all: add HiFive1 rev B board with RISC-V architecture

This page has been a big help in adding support for this new chip:
https://wiki.osdev.org/HiFive-1_Bare_Bones
Этот коммит содержится в:
Ayke van Laethem 2019-03-30 12:54:36 +01:00 коммит произвёл Ron Evans
родитель f0eb4eef5a
коммит ffa38b183b
37 изменённых файлов: 485 добавлений и 74 удалений

Просмотреть файл

@ -67,7 +67,7 @@ commands:
- run: go install . - run: go install .
- run: go test -v - run: go test -v
- run: make gen-device -j4 - run: make gen-device -j4
- run: make smoketest - run: make smoketest RISCV=0
- save_cache: - save_cache:
key: go-cache-{{ checksum "Gopkg.lock" }}-{{ .Environment.CIRCLE_BUILD_NUM }} key: go-cache-{{ checksum "Gopkg.lock" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths: paths:
@ -100,7 +100,7 @@ commands:
- llvm-source-linux - llvm-source-linux
- restore_cache: - restore_cache:
keys: keys:
- llvm-build-8-linux-v6 - llvm-build-8-linux-v7
- run: - run:
name: "Build LLVM" name: "Build LLVM"
command: | command: |
@ -118,7 +118,7 @@ commands:
make llvm-build make llvm-build
fi fi
- save_cache: - save_cache:
key: llvm-build-8-linux-v6 key: llvm-build-8-linux-v7
paths: paths:
llvm-build llvm-build
- run: - run:
@ -149,6 +149,11 @@ commands:
tar -C ~/lib -xf /tmp/tinygo.linux-amd64.tar.gz tar -C ~/lib -xf /tmp/tinygo.linux-amd64.tar.gz
ln -s ~/lib/tinygo/bin/tinygo /go/bin/tinygo ln -s ~/lib/tinygo/bin/tinygo /go/bin/tinygo
tinygo version tinygo version
- run:
name: "Download SiFive GNU toolchain"
command: |
curl -O https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-linux-ubuntu14.tar.gz
sudo tar -C /usr/local --strip-components=1 -xf riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-linux-ubuntu14.tar.gz
- run: make smoketest - run: make smoketest
build-macos: build-macos:
steps: steps:
@ -173,7 +178,7 @@ commands:
- llvm-project - llvm-project
- restore_cache: - restore_cache:
keys: keys:
- llvm-build-8-macos-v5 - llvm-build-8-macos-v6
- run: - run:
name: "Build LLVM" name: "Build LLVM"
command: | command: |
@ -185,7 +190,7 @@ commands:
make llvm-build make llvm-build
fi fi
- save_cache: - save_cache:
key: llvm-build-8-macos-v5 key: llvm-build-8-macos-v6
paths: paths:
llvm-build llvm-build
- run: - run:
@ -209,6 +214,11 @@ commands:
tar -C /usr/local/opt -xf /tmp/tinygo.darwin-amd64.tar.gz tar -C /usr/local/opt -xf /tmp/tinygo.darwin-amd64.tar.gz
ln -s /usr/local/opt/tinygo/bin/tinygo /usr/local/bin/tinygo ln -s /usr/local/opt/tinygo/bin/tinygo /usr/local/bin/tinygo
tinygo version tinygo version
- run:
name: "Download SiFive GNU toolchain"
command: |
curl -O https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-apple-darwin.tar.gz
sudo tar -C /usr/local --strip-components=1 -xf riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-apple-darwin.tar.gz
- run: make smoketest AVR=0 - run: make smoketest AVR=0

6
.gitignore предоставленный
Просмотреть файл

@ -5,10 +5,12 @@ src/device/avr/*.ld
src/device/avr/*.s src/device/avr/*.s
src/device/nrf/*.go src/device/nrf/*.go
src/device/nrf/*.s src/device/nrf/*.s
src/device/stm32/*.go
src/device/stm32/*.s
src/device/sam/*.go src/device/sam/*.go
src/device/sam/*.s src/device/sam/*.s
src/device/sifive/*.go
src/device/sifive/*.s
src/device/stm32/*.go
src/device/stm32/*.s
vendor vendor
llvm llvm
llvm-build llvm-build

2
.gitmodules предоставленный
Просмотреть файл

@ -9,7 +9,7 @@
url = https://github.com/avr-rust/avr-mcu.git url = https://github.com/avr-rust/avr-mcu.git
[submodule "lib/cmsis-svd"] [submodule "lib/cmsis-svd"]
path = lib/cmsis-svd path = lib/cmsis-svd
url = https://github.com/posborne/cmsis-svd url = https://github.com/tinygo-org/cmsis-svd
[submodule "lib/compiler-rt"] [submodule "lib/compiler-rt"]
path = lib/compiler-rt path = lib/compiler-rt
url = https://github.com/llvm-mirror/compiler-rt.git url = https://github.com/llvm-mirror/compiler-rt.git

Просмотреть файл

@ -41,7 +41,7 @@ fmt-check:
@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1 @unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
gen-device: gen-device-avr gen-device-nrf gen-device-sam gen-device-stm32 gen-device: gen-device-avr gen-device-nrf gen-device-sam gen-device-sifive gen-device-stm32
gen-device-avr: gen-device-avr:
./tools/gen-device-avr.py lib/avr/packs/atmega src/device/avr/ ./tools/gen-device-avr.py lib/avr/packs/atmega src/device/avr/
@ -56,6 +56,10 @@ gen-device-sam:
./tools/gen-device-svd.py lib/cmsis-svd/data/Atmel/ src/device/sam/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/Atmel ./tools/gen-device-svd.py lib/cmsis-svd/data/Atmel/ src/device/sam/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/Atmel
go fmt ./src/device/sam go fmt ./src/device/sam
gen-device-sifive:
./tools/gen-device-svd.py lib/cmsis-svd/data/SiFive-Community/ src/device/sifive/ --source=https://github.com/AdaCore/svd2ada/tree/master/CMSIS-SVD/SiFive-Community
go fmt ./src/device/sifive
gen-device-stm32: gen-device-stm32:
./tools/gen-device-svd.py lib/cmsis-svd/data/STMicro/ src/device/stm32/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro ./tools/gen-device-svd.py lib/cmsis-svd/data/STMicro/ src/device/stm32/ --source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro
go fmt ./src/device/stm32 go fmt ./src/device/stm32
@ -69,7 +73,7 @@ llvm-source: llvm-project/README.md
# Configure LLVM. # Configure LLVM.
TINYGO_SOURCE_DIR=$(shell pwd) TINYGO_SOURCE_DIR=$(shell pwd)
$(LLVM_BUILDDIR)/build.ninja: llvm-source $(LLVM_BUILDDIR)/build.ninja: llvm-source
mkdir -p $(LLVM_BUILDDIR); cd $(LLVM_BUILDDIR); cmake -G Ninja $(TINYGO_SOURCE_DIR)/llvm-project/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=OFF -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF mkdir -p $(LLVM_BUILDDIR); cd $(LLVM_BUILDDIR); cmake -G Ninja $(TINYGO_SOURCE_DIR)/llvm-project/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;RISCV" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=OFF -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF
# Build LLVM. # Build LLVM.
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja $(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
@ -123,6 +127,9 @@ smoketest:
ifneq ($(AVR), 0) ifneq ($(AVR), 0)
tinygo build -size short -o test.elf -target=arduino examples/blinky1 tinygo build -size short -o test.elf -target=arduino examples/blinky1
tinygo build -size short -o test.elf -target=digispark examples/blinky1 tinygo build -size short -o test.elf -target=digispark examples/blinky1
endif
ifneq ($(RISCV), 0)
tinygo build -size short -o test.elf -target=hifive1b examples/blinky1
endif endif
tinygo build -o wasm.wasm -target=wasm examples/wasm/export tinygo build -o wasm.wasm -target=wasm examples/wasm/export
tinygo build -o wasm.wasm -target=wasm examples/wasm/main tinygo build -o wasm.wasm -target=wasm examples/wasm/main

Просмотреть файл

@ -226,7 +226,7 @@ func (c *Compiler) Compile(mainPath string) []error {
return path return path
} else if path == "syscall" { } else if path == "syscall" {
for _, tag := range c.BuildTags { for _, tag := range c.BuildTags {
if tag == "avr" || tag == "cortexm" || tag == "darwin" { if tag == "avr" || tag == "cortexm" || tag == "darwin" || tag == "riscv" {
return path return path
} }
} }
@ -1304,11 +1304,11 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon) (llvm.Value, e
if fn := instr.StaticCallee(); fn != nil { if fn := instr.StaticCallee(); fn != nil {
name := fn.RelString(nil) name := fn.RelString(nil)
switch { switch {
case name == "device/arm.ReadRegister": case name == "device/arm.ReadRegister" || name == "device/riscv.ReadRegister":
return c.emitReadRegister(instr.Args) return c.emitReadRegister(name, instr.Args)
case name == "device/arm.Asm" || name == "device/avr.Asm": case name == "device/arm.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
return c.emitAsm(instr.Args) return c.emitAsm(instr.Args)
case name == "device/arm.AsmFull" || name == "device/avr.AsmFull": case name == "device/arm.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
return c.emitAsmFull(frame, instr) return c.emitAsmFull(frame, instr)
case strings.HasPrefix(name, "device/arm.SVCall"): case strings.HasPrefix(name, "device/arm.SVCall"):
return c.emitSVCall(frame, instr.Args) return c.emitSVCall(frame, instr.Args)

Просмотреть файл

@ -18,7 +18,7 @@ func (c *Compiler) needsStackObjects() bool {
return false return false
} }
for _, tag := range c.BuildTags { for _, tag := range c.BuildTags {
if tag == "cortexm" { if tag == "cortexm" || tag == "tinygo.riscv" {
return false return false
} }
} }

Просмотреть файл

@ -18,10 +18,19 @@ import (
// func ReadRegister(name string) uintptr // func ReadRegister(name string) uintptr
// //
// The register name must be a constant, for example "sp". // The register name must be a constant, for example "sp".
func (c *Compiler) emitReadRegister(args []ssa.Value) (llvm.Value, error) { func (c *Compiler) emitReadRegister(name string, args []ssa.Value) (llvm.Value, error) {
fnType := llvm.FunctionType(c.uintptrType, []llvm.Type{}, false) fnType := llvm.FunctionType(c.uintptrType, []llvm.Type{}, false)
regname := constant.StringVal(args[0].(*ssa.Const).Value) regname := constant.StringVal(args[0].(*ssa.Const).Value)
target := llvm.InlineAsm(fnType, "mov $0, "+regname, "=r", false, false, 0) var asm string
switch name {
case "device/arm.ReadRegister":
asm = "mov $0, " + regname
case "device/riscv.ReadRegister":
asm = "mv $0, " + regname
default:
panic("unknown architecture")
}
target := llvm.InlineAsm(fnType, asm, "=r", false, false, 0)
return c.builder.CreateCall(target, nil, ""), nil return c.builder.CreateCall(target, nil, ""), nil
} }

@ -1 +1 @@
Subproject commit b6f0a65ac37760f52d6ade23dd3205424d6c91fa Subproject commit 5910f3d115a53ead55c8158da24a8fa8bda1eb50

10
src/device/riscv/riscv.go Обычный файл
Просмотреть файл

@ -0,0 +1,10 @@
package riscv
// Run the given assembly code. The code will be marked as having side effects,
// as it doesn't produce output and thus would normally be eliminated by the
// optimizer.
func Asm(asm string)
// ReadRegister returns the contents of the specified register. The register
// must be a processor register, reachable with the "mov" instruction.
func ReadRegister(name string) uintptr

13
src/device/riscv/start.S Обычный файл
Просмотреть файл

@ -0,0 +1,13 @@
.section .init
.global _start
.type _start,@function
_start:
// Workaround for missing support of the la pseudo-instruction in Clang 8:
// https://reviews.llvm.org/D55325
lui sp, %hi(_stack_top)
addi sp, sp, %lo(_stack_top)
// see https://gnu-mcu-eclipse.github.io/arch/riscv/programmer/#the-gp-global-pointer-register
lui gp, %hi(__global_pointer$)
addi gp, gp, %lo(__global_pointer$)
call main

38
src/machine/board_fe310.go Обычный файл
Просмотреть файл

@ -0,0 +1,38 @@
// +build hifive1b
package machine
const (
P00 Pin = 0
P01 Pin = 1
P02 Pin = 2
P03 Pin = 3
P04 Pin = 4
P05 Pin = 5
P06 Pin = 6
P07 Pin = 7
P08 Pin = 8
P09 Pin = 9
P10 Pin = 10
P11 Pin = 11
P12 Pin = 12
P13 Pin = 13
P14 Pin = 14
P15 Pin = 15
P16 Pin = 16
P17 Pin = 17
P18 Pin = 18
P19 Pin = 19
P20 Pin = 20
P21 Pin = 21
P22 Pin = 22
P23 Pin = 23
P24 Pin = 24
P25 Pin = 25
P26 Pin = 26
P27 Pin = 27
P28 Pin = 28
P29 Pin = 29
P30 Pin = 30
P31 Pin = 31
)

19
src/machine/board_hifive1b.go Обычный файл
Просмотреть файл

@ -0,0 +1,19 @@
// +build hifive1b
package machine
const (
LED = LED1
LED1 = LED_RED
LED2 = LED_GREEN
LED3 = LED_BLUE
LED_RED = P22
LED_GREEN = P19
LED_BLUE = P21
)
const (
// TODO: figure out the pin numbers for these.
UART_TX_PIN = NoPin
UART_RX_PIN = NoPin
)

Просмотреть файл

@ -1,4 +1,4 @@
// +build !stm32f4disco // +build !stm32f4disco,!hifive1b
package machine package machine

54
src/machine/machine_fe310.go Обычный файл
Просмотреть файл

@ -0,0 +1,54 @@
// +build fe310
package machine
import (
"device/sifive"
)
type PinMode uint8
const (
PinInput PinMode = iota
PinOutput
)
// Configure this pin with the given configuration.
func (p Pin) Configure(config PinConfig) {
sifive.GPIO0.INPUT_EN.SetBits(1 << uint8(p))
if config.Mode == PinOutput {
sifive.GPIO0.OUTPUT_EN.SetBits(1 << uint8(p))
}
}
// Set the pin to high or low.
func (p Pin) Set(high bool) {
if high {
sifive.GPIO0.PORT.SetBits(1 << uint8(p))
} else {
sifive.GPIO0.PORT.ClearBits(1 << uint8(p))
}
}
type UART struct {
Bus *sifive.UART_Type
Buffer *RingBuffer
}
var (
UART0 = UART{Bus: sifive.UART0, Buffer: NewRingBuffer()}
)
func (uart UART) Configure(config UARTConfig) {
// Assuming a 16Mhz Crystal (which is Y1 on the HiFive1), the divisor for a
// 115200 baud rate is 138.
sifive.UART0.DIV.Set(138)
sifive.UART0.TXCTRL.Set(sifive.UART_TXCTRL_ENABLE)
}
func (uart UART) WriteByte(c byte) {
for sifive.UART0.TXDATA.Get()&sifive.UART_TXDATA_FULL != 0 {
}
sifive.UART0.TXDATA.Set(uint32(c))
}

Просмотреть файл

@ -1,4 +1,4 @@
// +build !avr,!nrf,!sam,!stm32 // +build !avr,!nrf,!sam,!sifive,!stm32
package machine package machine

Просмотреть файл

@ -1,4 +1,4 @@
// +build !stm32f407,!avr // +build !stm32f407,!avr,!hifive1b
package machine package machine

Просмотреть файл

@ -1,4 +1,4 @@
// +build avr nrf sam stm32 // +build avr nrf sam sifive stm32
package machine package machine

Просмотреть файл

@ -1,4 +1,4 @@
// +build avr cortexm wasm // +build avr cortexm tinygo.riscv wasm
package os package os

Просмотреть файл

@ -1,4 +1,4 @@
// +build darwin linux,!avr,!cortexm // +build darwin linux,!avr,!cortexm,!tinygo.riscv
package os package os

Просмотреть файл

@ -1,4 +1,4 @@
// +build arm,!avr,!cortexm // +build arm,!avr,!cortexm,!tinygo.riscv
package runtime package runtime

Просмотреть файл

@ -2,26 +2,11 @@
package runtime package runtime
import ( const GOARCH = "arm" // avr pretends to be arm
"unsafe"
)
const GOARCH = "avr"
// The bitness of the CPU (e.g. 8, 32, 64). // The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 8 const TargetBits = 8
//go:extern _heap_start
var heapStartSymbol unsafe.Pointer
//go:extern _heap_end
var heapEndSymbol unsafe.Pointer
var (
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
heapEnd = uintptr(unsafe.Pointer(&heapEndSymbol))
)
// Align on a word boundary. // Align on a word boundary.
func align(ptr uintptr) uintptr { func align(ptr uintptr) uintptr {
// No alignment necessary on the AVR. // No alignment necessary on the AVR.

Просмотреть файл

@ -3,8 +3,6 @@
package runtime package runtime
import ( import (
"unsafe"
"device/arm" "device/arm"
) )
@ -13,29 +11,6 @@ const GOARCH = "arm"
// The bitness of the CPU (e.g. 8, 32, 64). // The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 32 const TargetBits = 32
//go:extern _heap_start
var heapStartSymbol unsafe.Pointer
//go:extern _heap_end
var heapEndSymbol unsafe.Pointer
//go:extern _globals_start
var globalsStartSymbol unsafe.Pointer
//go:extern _globals_end
var globalsEndSymbol unsafe.Pointer
//go:extern _stack_top
var stackTopSymbol unsafe.Pointer
var (
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
heapEnd = uintptr(unsafe.Pointer(&heapEndSymbol))
globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
globalsEnd = uintptr(unsafe.Pointer(&globalsEndSymbol))
stackTop = uintptr(unsafe.Pointer(&stackTopSymbol))
)
// Align on word boundary. // Align on word boundary.
func align(ptr uintptr) uintptr { func align(ptr uintptr) uintptr {
return (ptr + 3) &^ 3 return (ptr + 3) &^ 3

19
src/runtime/arch_tinygoriscv.go Обычный файл
Просмотреть файл

@ -0,0 +1,19 @@
// +build tinygo.riscv
package runtime
import "device/riscv"
const GOARCH = "arm" // riscv pretends to be arm
// The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 32
// Align on word boundary.
func align(ptr uintptr) uintptr {
return (ptr + 3) &^ 3
}
func getCurrentStackPointer() uintptr {
return riscv.ReadRegister("sp")
}

30
src/runtime/baremetal.go Обычный файл
Просмотреть файл

@ -0,0 +1,30 @@
// +build avr cortexm tinygo.riscv
package runtime
import (
"unsafe"
)
//go:extern _heap_start
var heapStartSymbol unsafe.Pointer
//go:extern _heap_end
var heapEndSymbol unsafe.Pointer
//go:extern _globals_start
var globalsStartSymbol unsafe.Pointer
//go:extern _globals_end
var globalsEndSymbol unsafe.Pointer
//go:extern _stack_top
var stackTopSymbol unsafe.Pointer
var (
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
heapEnd = uintptr(unsafe.Pointer(&heapEndSymbol))
globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
globalsEnd = uintptr(unsafe.Pointer(&globalsEndSymbol))
stackTop = uintptr(unsafe.Pointer(&stackTopSymbol))
)

Просмотреть файл

@ -1,5 +1,5 @@
// +build gc.conservative // +build gc.conservative
// +build cortexm // +build cortexm tinygo.riscv
package runtime package runtime

Просмотреть файл

@ -1,5 +1,5 @@
// +build gc.conservative // +build gc.conservative
// +build !cortexm // +build !cortexm,!tinygo.riscv
package runtime package runtime

Просмотреть файл

@ -1,5 +1,5 @@
// +build gc.conservative // +build gc.conservative
// +build !cortexm // +build !cortexm,!tinygo.riscv
package runtime package runtime

Просмотреть файл

@ -1,5 +1,5 @@
// +build gc.conservative // +build gc.conservative
// +build cortexm // +build cortexm tinygo.riscv
package runtime package runtime

115
src/runtime/runtime_fe310.go Обычный файл
Просмотреть файл

@ -0,0 +1,115 @@
// +build fe310
// This file implements target-specific things for the FE310 chip as used in the
// HiFive1.
package runtime
import (
"machine"
"unsafe"
"device/riscv"
"device/sifive"
)
type timeUnit int64
const tickMicros = 32768 // RTC runs at 32.768kHz
//go:extern _sbss
var _sbss unsafe.Pointer
//go:extern _ebss
var _ebss unsafe.Pointer
//go:extern _sdata
var _sdata unsafe.Pointer
//go:extern _sidata
var _sidata unsafe.Pointer
//go:extern _edata
var _edata unsafe.Pointer
//go:export main
func main() {
preinit()
initAll()
callMain()
abort()
}
func init() {
pric_init()
machine.UART0.Configure(machine.UARTConfig{})
}
func pric_init() {
// Make sure the HFROSC is on
sifive.PRIC.HFROSCCFG.SetBits(sifive.PRIC_HFROSCCFG_ENABLE)
// Run off 16 MHz Crystal for accuracy.
sifive.PRIC.PLLCFG.SetBits(sifive.PRIC_PLLCFG_REFSEL | sifive.PRIC_PLLCFG_BYPASS)
sifive.PRIC.PLLCFG.SetBits(sifive.PRIC_PLLCFG_SEL)
// Turn off HFROSC to save power
sifive.PRIC.HFROSCCFG.ClearBits(sifive.PRIC_HFROSCCFG_ENABLE)
// Enable the RTC.
sifive.RTC.CONFIG.Set(sifive.RTC_CONFIG_ENALWAYS)
}
func preinit() {
// Initialize .bss: zero-initialized global variables.
ptr := uintptr(unsafe.Pointer(&_sbss))
for ptr != uintptr(unsafe.Pointer(&_ebss)) {
*(*uint32)(unsafe.Pointer(ptr)) = 0
ptr += 4
}
// Initialize .data: global variables initialized from flash.
src := uintptr(unsafe.Pointer(&_sidata))
dst := uintptr(unsafe.Pointer(&_sdata))
for dst != uintptr(unsafe.Pointer(&_edata)) {
*(*uint32)(unsafe.Pointer(dst)) = *(*uint32)(unsafe.Pointer(src))
dst += 4
src += 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.HI.Get()
for {
lowBits := sifive.RTC.LO.Get()
newHighBits := sifive.RTC.HI.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 {
}
}
func abort() {
// lock up forever
for {
riscv.Asm("wfi")
}
}

19
src/runtime/runtime_tinygoriscv.go Обычный файл
Просмотреть файл

@ -0,0 +1,19 @@
// +build tinygo.riscv
package runtime
import "unsafe"
// Implement memset for LLVM.
//go:export memset
func libc_memset(ptr unsafe.Pointer, c byte, size uintptr) {
for i := uintptr(0); i < size; i++ {
*(*byte)(unsafe.Pointer(uintptr(ptr) + i)) = c
}
}
// Implement memmove for LLVM.
//go:export memmove
func libc_memmove(dst, src unsafe.Pointer, size uintptr) {
memmove(dst, src, size)
}

Просмотреть файл

@ -1,4 +1,4 @@
// +build darwin linux,!avr,!cortexm // +build darwin linux,!avr,!cortexm,!tinygo.riscv
package runtime package runtime

5
targets/fe310.json Обычный файл
Просмотреть файл

@ -0,0 +1,5 @@
{
"inherits": ["riscv"],
"features": ["+a", "+c", "+m"],
"build-tags": ["fe310", "sifive"]
}

7
targets/hifive1b.json Обычный файл
Просмотреть файл

@ -0,0 +1,7 @@
{
"inherits": ["fe310"],
"build-tags": ["hifive1b"],
"ldflags": [
"-T", "targets/hifive1b.ld"
]
}

10
targets/hifive1b.ld Обычный файл
Просмотреть файл

@ -0,0 +1,10 @@
MEMORY
{
FLASH_TEXT (rw) : ORIGIN = 0x20010000, LENGTH = 0x6a120
RAM (xrw) : ORIGIN = 0x80000000, LENGTH = 0x4000
}
_stack_size = 2K;
INCLUDE "targets/riscv.ld"

25
targets/riscv.json Обычный файл
Просмотреть файл

@ -0,0 +1,25 @@
{
"llvm-target": "riscv32--none",
"goos": "linux",
"goarch": "arm",
"build-tags": ["tinygo.riscv", "linux", "arm"],
"gc": "conservative",
"compiler": "riscv64-unknown-elf-gcc",
"linker": "riscv64-unknown-elf-ld",
"cflags": [
"-march=rv32imac",
"-mabi=ilp32",
"-Os",
"-Werror",
"-nostdinc",
"-fno-exceptions", "-fno-unwind-tables",
"-ffunction-sections", "-fdata-sections"
],
"ldflags": [
"-melf32lriscv",
"--gc-sections"
],
"extra-files": [
"src/device/riscv/start.S"
]
}

56
targets/riscv.ld Обычный файл
Просмотреть файл

@ -0,0 +1,56 @@
SECTIONS
{
.text :
{
KEEP(*(.init))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(4);
} >FLASH_TEXT
/* Put the stack at the bottom of RAM, so that the application will
* crash on stack overflow instead of silently corrupting memory.
* See: http://blog.japaric.io/stack-overflow-protection/ */
.stack :
{
. = ALIGN(4);
. += _stack_size;
_stack_top = .;
} >RAM
/* Start address (in flash) of .data, used by startup code. */
_sidata = LOADADDR(.data);
/* Globals with initial value */
.data :
{
. = ALIGN(4);
/* see https://gnu-mcu-eclipse.github.io/arch/riscv/programmer/#the-gp-global-pointer-register */
PROVIDE( __global_pointer$ = . + (4K / 2) );
_sdata = .; /* used by startup code */
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .; /* used by startup code */
} >RAM AT>FLASH_TEXT
/* Zero-initialized globals */
.bss :
{
. = ALIGN(4);
_sbss = .; /* used by startup code */
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* used by startup code */
} >RAM
}
/* For the memory allocator. */
_heap_start = _ebss;
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
_globals_start = _sdata;
_globals_end = _ebss;

Просмотреть файл

@ -151,7 +151,10 @@ def readSVD(path, sourceURL):
dimIncrement = None dimIncrement = None
else: else:
dim = int(getText(cluster.find('dim'))) dim = int(getText(cluster.find('dim')))
dimIncrement = int(getText(cluster.find('dimIncrement')), 0) if dim == 1:
dimIncrement = None
else:
dimIncrement = int(getText(cluster.find('dimIncrement')), 0)
clusterRegisters = [] clusterRegisters = []
for regEl in cluster.findall('register'): for regEl in cluster.findall('register'):
clusterRegisters.extend(parseRegister(groupName or name, regEl, baseAddress + clusterOffset, clusterPrefix)) clusterRegisters.extend(parseRegister(groupName or name, regEl, baseAddress + clusterOffset, clusterPrefix))
@ -241,7 +244,7 @@ def parseBitfields(groupName, regName, fieldsEls, bitfieldPrefix=''):
}) })
for enumEl in fieldEl.findall('enumeratedValues/enumeratedValue'): for enumEl in fieldEl.findall('enumeratedValues/enumeratedValue'):
enumName = getText(enumEl.find('name')) enumName = getText(enumEl.find('name'))
enumDescription = getText(enumEl.find('description')) enumDescription = getText(enumEl.find('description')).replace('\n', ' ')
enumValue = int(getText(enumEl.find('value')), 0) enumValue = int(getText(enumEl.find('value')), 0)
fields.append({ fields.append({
'name': '{}_{}{}_{}_{}'.format(groupName, bitfieldPrefix, regName, fieldName, enumName), 'name': '{}_{}{}_{}_{}'.format(groupName, bitfieldPrefix, regName, fieldName, enumName),