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 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
предоставленный
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
предоставленный
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
|
||||||
|
|
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
|
@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
Обычный файл
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
|
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
|
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
Обычный файл
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 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
Обычный файл
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
|
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,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),
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче