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
Этот коммит содержится в:
родитель
f0eb4eef5a
коммит
ffa38b183b
37 изменённых файлов: 485 добавлений и 74 удалений
|
@ -67,7 +67,7 @@ commands:
|
|||
- run: go install .
|
||||
- run: go test -v
|
||||
- run: make gen-device -j4
|
||||
- run: make smoketest
|
||||
- run: make smoketest RISCV=0
|
||||
- save_cache:
|
||||
key: go-cache-{{ checksum "Gopkg.lock" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
|
||||
paths:
|
||||
|
@ -100,7 +100,7 @@ commands:
|
|||
- llvm-source-linux
|
||||
- restore_cache:
|
||||
keys:
|
||||
- llvm-build-8-linux-v6
|
||||
- llvm-build-8-linux-v7
|
||||
- run:
|
||||
name: "Build LLVM"
|
||||
command: |
|
||||
|
@ -118,7 +118,7 @@ commands:
|
|||
make llvm-build
|
||||
fi
|
||||
- save_cache:
|
||||
key: llvm-build-8-linux-v6
|
||||
key: llvm-build-8-linux-v7
|
||||
paths:
|
||||
llvm-build
|
||||
- run:
|
||||
|
@ -149,6 +149,11 @@ commands:
|
|||
tar -C ~/lib -xf /tmp/tinygo.linux-amd64.tar.gz
|
||||
ln -s ~/lib/tinygo/bin/tinygo /go/bin/tinygo
|
||||
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
|
||||
build-macos:
|
||||
steps:
|
||||
|
@ -173,7 +178,7 @@ commands:
|
|||
- llvm-project
|
||||
- restore_cache:
|
||||
keys:
|
||||
- llvm-build-8-macos-v5
|
||||
- llvm-build-8-macos-v6
|
||||
- run:
|
||||
name: "Build LLVM"
|
||||
command: |
|
||||
|
@ -185,7 +190,7 @@ commands:
|
|||
make llvm-build
|
||||
fi
|
||||
- save_cache:
|
||||
key: llvm-build-8-macos-v5
|
||||
key: llvm-build-8-macos-v6
|
||||
paths:
|
||||
llvm-build
|
||||
- run:
|
||||
|
@ -209,6 +214,11 @@ commands:
|
|||
tar -C /usr/local/opt -xf /tmp/tinygo.darwin-amd64.tar.gz
|
||||
ln -s /usr/local/opt/tinygo/bin/tinygo /usr/local/bin/tinygo
|
||||
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
|
||||
|
||||
|
||||
|
|
6
.gitignore
предоставленный
6
.gitignore
предоставленный
|
@ -5,10 +5,12 @@ src/device/avr/*.ld
|
|||
src/device/avr/*.s
|
||||
src/device/nrf/*.go
|
||||
src/device/nrf/*.s
|
||||
src/device/stm32/*.go
|
||||
src/device/stm32/*.s
|
||||
src/device/sam/*.go
|
||||
src/device/sam/*.s
|
||||
src/device/sifive/*.go
|
||||
src/device/sifive/*.s
|
||||
src/device/stm32/*.go
|
||||
src/device/stm32/*.s
|
||||
vendor
|
||||
llvm
|
||||
llvm-build
|
||||
|
|
2
.gitmodules
предоставленный
2
.gitmodules
предоставленный
|
@ -9,7 +9,7 @@
|
|||
url = https://github.com/avr-rust/avr-mcu.git
|
||||
[submodule "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"]
|
||||
path = lib/compiler-rt
|
||||
url = https://github.com/llvm-mirror/compiler-rt.git
|
||||
|
|
11
Makefile
11
Makefile
|
@ -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
|
||||
|
||||
|
||||
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:
|
||||
./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
|
||||
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:
|
||||
./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
|
||||
|
@ -69,7 +73,7 @@ llvm-source: llvm-project/README.md
|
|||
# Configure LLVM.
|
||||
TINYGO_SOURCE_DIR=$(shell pwd)
|
||||
$(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.
|
||||
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
|
||||
|
@ -123,6 +127,9 @@ smoketest:
|
|||
ifneq ($(AVR), 0)
|
||||
tinygo build -size short -o test.elf -target=arduino 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
|
||||
tinygo build -o wasm.wasm -target=wasm examples/wasm/export
|
||||
tinygo build -o wasm.wasm -target=wasm examples/wasm/main
|
||||
|
|
|
@ -226,7 +226,7 @@ func (c *Compiler) Compile(mainPath string) []error {
|
|||
return path
|
||||
} else if path == "syscall" {
|
||||
for _, tag := range c.BuildTags {
|
||||
if tag == "avr" || tag == "cortexm" || tag == "darwin" {
|
||||
if tag == "avr" || tag == "cortexm" || tag == "darwin" || tag == "riscv" {
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
@ -1304,11 +1304,11 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon) (llvm.Value, e
|
|||
if fn := instr.StaticCallee(); fn != nil {
|
||||
name := fn.RelString(nil)
|
||||
switch {
|
||||
case name == "device/arm.ReadRegister":
|
||||
return c.emitReadRegister(instr.Args)
|
||||
case name == "device/arm.Asm" || name == "device/avr.Asm":
|
||||
case name == "device/arm.ReadRegister" || name == "device/riscv.ReadRegister":
|
||||
return c.emitReadRegister(name, instr.Args)
|
||||
case name == "device/arm.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
|
||||
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)
|
||||
case strings.HasPrefix(name, "device/arm.SVCall"):
|
||||
return c.emitSVCall(frame, instr.Args)
|
||||
|
|
|
@ -18,7 +18,7 @@ func (c *Compiler) needsStackObjects() bool {
|
|||
return false
|
||||
}
|
||||
for _, tag := range c.BuildTags {
|
||||
if tag == "cortexm" {
|
||||
if tag == "cortexm" || tag == "tinygo.riscv" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,19 @@ import (
|
|||
// func ReadRegister(name string) uintptr
|
||||
//
|
||||
// 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)
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b6f0a65ac37760f52d6ade23dd3205424d6c91fa
|
||||
Subproject commit 5910f3d115a53ead55c8158da24a8fa8bda1eb50
|
10
src/device/riscv/riscv.go
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
|
||||
|
||||
|
|
54
src/machine/machine_fe310.go
Обычный файл
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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build !stm32f407,!avr
|
||||
// +build !stm32f407,!avr,!hifive1b
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build avr nrf sam stm32
|
||||
// +build avr nrf sam sifive stm32
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build avr cortexm wasm
|
||||
// +build avr cortexm tinygo.riscv wasm
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build darwin linux,!avr,!cortexm
|
||||
// +build darwin linux,!avr,!cortexm,!tinygo.riscv
|
||||
|
||||
package os
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build arm,!avr,!cortexm
|
||||
// +build arm,!avr,!cortexm,!tinygo.riscv
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
@ -2,26 +2,11 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const GOARCH = "avr"
|
||||
const GOARCH = "arm" // avr pretends to be arm
|
||||
|
||||
// The bitness of the CPU (e.g. 8, 32, 64).
|
||||
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.
|
||||
func align(ptr uintptr) uintptr {
|
||||
// No alignment necessary on the AVR.
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"device/arm"
|
||||
)
|
||||
|
||||
|
@ -13,29 +11,6 @@ const GOARCH = "arm"
|
|||
// The bitness of the CPU (e.g. 8, 32, 64).
|
||||
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.
|
||||
func align(ptr uintptr) uintptr {
|
||||
return (ptr + 3) &^ 3
|
||||
|
|
19
src/runtime/arch_tinygoriscv.go
Обычный файл
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
Обычный файл
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 cortexm
|
||||
// +build cortexm tinygo.riscv
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build gc.conservative
|
||||
// +build !cortexm
|
||||
// +build !cortexm,!tinygo.riscv
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build gc.conservative
|
||||
// +build !cortexm
|
||||
// +build !cortexm,!tinygo.riscv
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// +build gc.conservative
|
||||
// +build cortexm
|
||||
// +build cortexm tinygo.riscv
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
115
src/runtime/runtime_fe310.go
Обычный файл
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
Обычный файл
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
|
||||
|
||||
|
|
5
targets/fe310.json
Обычный файл
5
targets/fe310.json
Обычный файл
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"inherits": ["riscv"],
|
||||
"features": ["+a", "+c", "+m"],
|
||||
"build-tags": ["fe310", "sifive"]
|
||||
}
|
7
targets/hifive1b.json
Обычный файл
7
targets/hifive1b.json
Обычный файл
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"inherits": ["fe310"],
|
||||
"build-tags": ["hifive1b"],
|
||||
"ldflags": [
|
||||
"-T", "targets/hifive1b.ld"
|
||||
]
|
||||
}
|
10
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
Обычный файл
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
Обычный файл
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,6 +151,9 @@ def readSVD(path, sourceURL):
|
|||
dimIncrement = None
|
||||
else:
|
||||
dim = int(getText(cluster.find('dim')))
|
||||
if dim == 1:
|
||||
dimIncrement = None
|
||||
else:
|
||||
dimIncrement = int(getText(cluster.find('dimIncrement')), 0)
|
||||
clusterRegisters = []
|
||||
for regEl in cluster.findall('register'):
|
||||
|
@ -241,7 +244,7 @@ def parseBitfields(groupName, regName, fieldsEls, bitfieldPrefix=''):
|
|||
})
|
||||
for enumEl in fieldEl.findall('enumeratedValues/enumeratedValue'):
|
||||
enumName = getText(enumEl.find('name'))
|
||||
enumDescription = getText(enumEl.find('description'))
|
||||
enumDescription = getText(enumEl.find('description')).replace('\n', ' ')
|
||||
enumValue = int(getText(enumEl.find('value')), 0)
|
||||
fields.append({
|
||||
'name': '{}_{}{}_{}_{}'.format(groupName, bitfieldPrefix, regName, fieldName, enumName),
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче