Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,28 @@ commands:
command: |
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
install-xtensa-toolchain:
parameters:
variant:
type: string
steps:
- run:
name: "Install Xtensa toolchain"
command: |
curl -L https://github.com/espressif/crosstool-NG/releases/download/esp-2020r2/xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz -o xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo tar -C /usr/local -xf xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo ln -s /usr/local/xtensa-esp32-elf/bin/xtensa-esp32-elf-ld /usr/local/bin/xtensa-esp32-elf-ld
rm xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
llvm-source-linux:
steps:
- restore_cache:
keys:
- llvm-source-10-v0
- llvm-source-10-v1
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-10-v0
key: llvm-source-10-v1
paths:
- llvm-project
build-wasi-libc:
Expand Down Expand Up @@ -95,7 +107,7 @@ commands:
- lib/wasi-libc/sysroot
- run: go test -v -tags=llvm<<parameters.llvm>> ./cgo ./compileopts ./interp ./transform .
- run: make gen-device -j4
- run: make smoketest
- run: make smoketest XTENSA=0
- run: make wasmtest
- save_cache:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
Expand All @@ -121,14 +133,16 @@ commands:
gcc-avr \
avr-libc
- install-node
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-10-linux-v0-assert
- llvm-build-10-linux-v1-assert
- run:
name: "Build LLVM"
command: |
Expand All @@ -146,7 +160,7 @@ commands:
make ASSERT=1 llvm-build
fi
- save_cache:
key: llvm-build-10-linux-v0-assert
key: llvm-build-10-linux-v1-assert
paths:
llvm-build
- run: make ASSERT=1
Expand Down Expand Up @@ -179,14 +193,16 @@ commands:
gcc-avr \
avr-libc
- install-node
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-10-linux-v0
- llvm-build-10-linux-v1
- run:
name: "Build LLVM"
command: |
Expand All @@ -204,7 +220,7 @@ commands:
make llvm-build
fi
- save_cache:
key: llvm-build-10-linux-v0
key: llvm-build-10-linux-v1
paths:
llvm-build
- build-wasi-libc
Expand Down Expand Up @@ -250,23 +266,25 @@ commands:
sudo tar -C /usr/local -xzf go1.14.darwin-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin/go
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu
- install-xtensa-toolchain:
variant: "macos"
- restore_cache:
keys:
- go-cache-macos-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-macos-v2-{{ checksum "go.mod" }}
- restore_cache:
keys:
- llvm-source-10-macos-v0
- llvm-source-10-macos-v1
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-10-macos-v0
key: llvm-source-10-macos-v1
paths:
- llvm-project
- restore_cache:
keys:
- llvm-build-10-macos-v0
- llvm-build-10-macos-v1
- run:
name: "Build LLVM"
command: |
Expand All @@ -278,7 +296,7 @@ commands:
make llvm-build
fi
- save_cache:
key: llvm-build-10-macos-v0
key: llvm-build-10-macos-v1
paths:
llvm-build
- restore_cache:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ docs/_build
src/device/avr/*.go
src/device/avr/*.ld
src/device/avr/*.s
src/device/esp/*.go
src/device/nrf/*.go
src/device/nrf/*.s
src/device/nxp/*.go
Expand Down
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,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-sifive gen-device-stm32 gen-device-kendryte gen-device-nxp
gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-stm32 gen-device-kendryte gen-device-nxp

gen-device-avr:
$(GO) build -o ./build/gen-device-avr ./tools/gen-device-avr/
Expand All @@ -129,6 +129,10 @@ gen-device-avr:
build/gen-device-svd: ./tools/gen-device-svd/*.go
$(GO) build -o $@ ./tools/gen-device-svd/

gen-device-esp: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/Espressif-Community -interrupts=software lib/cmsis-svd/data/Espressif-Community/ src/device/esp/
GO111MODULE=off $(GO) fmt ./src/device/esp

gen-device-nrf: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/NordicSemiconductor/nrfx/tree/master/mdk lib/nrfx/mdk/ src/device/nrf/
GO111MODULE=off $(GO) fmt ./src/device/nrf
Expand Down Expand Up @@ -156,13 +160,13 @@ gen-device-stm32: build/gen-device-svd

# Get LLVM sources.
$(LLVM_PROJECTDIR)/README.md:
git clone -b release/10.x --depth=1 https://github.com/llvm/llvm-project $(LLVM_PROJECTDIR)
git clone -b xtensa_release_10.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
llvm-source: $(LLVM_PROJECTDIR)/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_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF $(LLVM_OPTION)
mkdir -p $(LLVM_BUILDDIR); cd $(LLVM_BUILDDIR); cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;Xtensa" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF $(LLVM_OPTION)

# Build LLVM.
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
Expand Down Expand Up @@ -341,6 +345,9 @@ ifneq ($(AVR), 0)
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=digispark -gc=leaking examples/blinky1
@$(MD5SUM) test.hex
endif
ifneq ($(XTENSA), 0)
$(TINYGO) build -size short -o test.elf -target=esp32 examples/serial
endif
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
@$(MD5SUM) test.hex
Expand Down
14 changes: 9 additions & 5 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ jobs:
inputs:
version: '1.15'
- checkout: self
- task: CacheBeta@0
- task: Cache@2
displayName: Cache LLVM source
inputs:
key: llvm-source-10-windows-v0
key: llvm-source-10-windows-v1
path: llvm-project
- task: Bash@3
displayName: Download LLVM source
inputs:
targetType: inline
script: make llvm-source
script: |
make llvm-source
# Workaround for bad symlinks:
# https://github.com/microsoft/azure-pipelines-tasks/issues/13418
rm -f llvm-project/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
- task: CacheBeta@0
displayName: Cache LLVM build
inputs:
key: llvm-build-10-windows-v0
key: llvm-build-10-windows-v1
path: llvm-build
- task: Bash@3
displayName: Build LLVM
Expand Down Expand Up @@ -80,4 +84,4 @@ jobs:
script: |
export PATH="$PATH:./llvm-build/bin:/c/Program Files/qemu"
unset GOROOT
make smoketest TINYGO=build/tinygo AVR=0
make smoketest TINYGO=build/tinygo AVR=0 XTENSA=0
52 changes: 52 additions & 0 deletions src/device/esp/esp32.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

// The following definitions were copied from:
// esp-idf/components/xtensa/include/xtensa/corebits.h
#define PS_WOE_MASK 0x00040000
#define PS_OWB_MASK 0x00000F00
#define PS_CALLINC_MASK 0x00030000
#define PS_WOE PS_WOE_MASK

// Only calling it call_start_cpu0 for consistency with ESP-IDF.
.section .text.call_start_cpu0
1:
.long _stack_top
.global call_start_cpu0
call_start_cpu0:
// We need to set the stack pointer to a different value. This is somewhat
// complicated in the Xtensa architecture. The code below is a modified
// version of the following code:
// https://github.com/espressif/esp-idf/blob/c77c4ccf/components/xtensa/include/xt_instr_macros.h#L47

// Disable WOE.
rsr.ps a2
movi a3, ~(PS_WOE_MASK)
and a2, a2, a3
wsr.ps a2
rsync

// Set WINDOWBASE to 1 << WINDOWSTART.
rsr.windowbase a2
ssl a2
movi a2, 1
sll a2, a2
wsr.windowstart a2
rsync

// Load new stack pointer.
l32r sp, 1b

// Re-enable WOE.
rsr.ps a2
movi a3, PS_WOE
or a2, a2, a3
wsr.ps a2
rsync

// Jump to the runtime start function written in Go.
j main

.section .text.tinygo_scanCurrentStack
.global tinygo_scanCurrentStack
tinygo_scanCurrentStack:
// TODO: save callee saved registers on the stack
j tinygo_scanstack
44 changes: 44 additions & 0 deletions src/machine/machine_esp32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// +build esp32

package machine

import "device/esp"

const peripheralClock = 80000000 // 80MHz

type PinMode uint8

const (
PinOutput PinMode = iota
PinInput
)

func (p Pin) Set(value bool)

var (
UART0 = UART{Bus: esp.UART0, Buffer: NewRingBuffer()}
UART1 = UART{Bus: esp.UART1, Buffer: NewRingBuffer()}
UART2 = UART{Bus: esp.UART2, Buffer: NewRingBuffer()}
)

type UART struct {
Bus *esp.UART_Type
Buffer *RingBuffer
}

func (uart UART) Configure(config UARTConfig) {
if config.BaudRate == 0 {
config.BaudRate = 115200
}
uart.Bus.CLKDIV.Set(peripheralClock / config.BaudRate)
}

func (uart UART) WriteByte(b byte) error {
for (uart.Bus.STATUS.Get()>>16)&0xff >= 128 {
// Read UART_TXFIFO_CNT from the status register, which indicates how
// many bytes there are in the transmit buffer. Wait until there are
// less than 128 bytes in this buffer (the default buffer size).
}
uart.Bus.TX_FIFO.Set(b)
return nil
}
2 changes: 1 addition & 1 deletion src/machine/uart.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build avr nrf sam sifive stm32 k210 nxp
// +build avr esp nrf sam sifive stm32 k210 nxp

package machine

Expand Down
15 changes: 15 additions & 0 deletions src/runtime/arch_xtensa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// +build xtensa

package runtime

const GOARCH = "arm" // xtensa pretends to be arm

// The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 32

// Align on a word boundary.
func align(ptr uintptr) uintptr {
return (ptr + 3) &^ 3
}

func getCurrentStackPointer() uintptr
31 changes: 31 additions & 0 deletions src/runtime/interrupt/interrupt_xtensa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// +build xtensa

package interrupt

import "device"

// State represents the previous global interrupt state.
type State uintptr

// Disable disables all interrupts and returns the previous interrupt state. It
// can be used in a critical section like this:
//
// state := interrupt.Disable()
// // critical section
// interrupt.Restore(state)
//
// Critical sections can be nested. Make sure to call Restore in the same order
// as you called Disable (this happens naturally with the pattern above).
func Disable() (state State) {
return State(device.AsmFull("rsil {}, 15", nil))
}

// Restore restores interrupts to what they were before. Give the previous state
// returned by Disable as a parameter. If interrupts were disabled before
// calling Disable, this will not re-enable interrupts, allowing for nested
// cricital sections.
func Restore(state State) {
device.AsmFull("wsr {state}, PS", map[string]interface{}{
"state": state,
})
}
Loading