Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Llvm mos #4051

Open
wants to merge 6 commits into
base: release
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ gen-device-stm32: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/tinygo-org/stm32-svd lib/stm32-svd/svd src/device/stm32/
GO111MODULE=off $(GO) fmt ./src/device/stm32

gen-device-6502: build/gen-device-svd
./build/gen-device-svd lib/cmsis-svd/data/MOS src/device/mos/
GO111MODULE=off $(GO) fmt ./src/device/mos

gen-device-rp: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/RaspberryPi lib/cmsis-svd/data/RaspberryPi/ src/device/rp/
GO111MODULE=off $(GO) fmt ./src/device/rp
Expand All @@ -238,13 +242,13 @@ gen-device-renesas: build/gen-device-svd

# Get LLVM sources.
$(LLVM_PROJECTDIR)/llvm:
git clone -b xtensa_release_16.x --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
git clone --depth=1 https://github.com/llvm-mos/llvm-mos $(LLVM_PROJECTDIR) && cd $(LLVM_PROJECTDIR) && git checkout a6f990e5ae4e6e287997ee71928ea65b99a40fe0 && cd ..
llvm-source: $(LLVM_PROJECTDIR)/llvm

# Configure LLVM.
TINYGO_SOURCE_DIR=$(shell pwd)
$(LLVM_BUILDDIR)/build.ninja:
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_ZSTD=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=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=MOS" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_ZSTD=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF $(LLVM_OPTION)

# Build LLVM.
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
Expand Down
104 changes: 104 additions & 0 deletions src/device/mos/c64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Automatically generated file. DO NOT EDIT.
// Generated by gen-device-svd.go from 6502.svd, see <unknown>

//go:build mos && c64

//
//

package mos

import (
"runtime/volatile"
"unsafe"
)

// Some information about this device.
const (
Device = "C64"
)

// Interrupt numbers.
const (
// Highest interrupt number on this device.
IRQ_max = 0
)

// Pseudo function call that is replaced by the compiler with the actual
// functions registered through interrupt.New.
//
//go:linkname callHandlers runtime/interrupt.callHandlers
func callHandlers(num int)

// Peripherals.
var (
// MOS 6510 Processor
CPU = (*CPU_Type)(unsafe.Pointer(uintptr(0x1)))

// Video Interface Chip
VICII = (*VICII_Type)(unsafe.Pointer(uintptr(0xd000)))

// Sound Interface Device
SID = (*SID_Type)(unsafe.Pointer(uintptr(0xd400)))

// Complex Interface Adapter 1
CIA1 = (*CIA1_Type)(unsafe.Pointer(uintptr(0xdc00)))

// Complex Interface Adapter 2
CIA2 = (*CIA2_Type)(unsafe.Pointer(uintptr(0xdd00)))

// Main Memory
Memory = (*Memory_Type)(unsafe.Pointer(uintptr(0x0)))
)

// MOS 6510 Processor
type CPU_Type struct {
_ byte
CPU_PORT volatile.Register8 // 0x1
}

// Video Interface Chip
type VICII_Type struct {
VIC volatile.Register8 // 0x0
}

// Sound Interface Device
type SID_Type struct {
SID volatile.Register8 // 0x0
}

// Complex Interface Adapter 1
type CIA1_Type struct {
_ [14]byte
CIA1ControlA volatile.Register8 // 0xE
}

// Complex Interface Adapter 2
type CIA2_Type struct {
}

// Main Memory
type Memory_Type struct {
_ [1024]byte
DEFAULT_VIDEO_MEMORY volatile.Register8 // 0x400
_ [54271]byte
COLOR_RAM volatile.Register8 // 0xD800
}

// Constants for CPU: MOS 6510 Processor
const ()

// Constants for VICII: Video Interface Chip
const ()

// Constants for SID: Sound Interface Device
const ()

// Constants for CIA1: Complex Interface Adapter 1
const ()

// Constants for CIA2: Complex Interface Adapter 2
const ()

// Constants for Memory: Main Memory
const ()
65 changes: 65 additions & 0 deletions src/device/mos/c64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Automatically generated file. DO NOT EDIT.
// Generated by gen-device-svd.go from 6502.svd, see <unknown>

//
//


.syntax unified

// This is the default handler for interrupts, if triggered but not defined.
.section .text.Default_Handler
.global Default_Handler
.type Default_Handler, %function
Default_Handler:
wfe
b Default_Handler
.size Default_Handler, .-Default_Handler

// Avoid the need for repeated .weak and .set instructions.
.macro IRQ handler
.weak \handler
.set \handler, Default_Handler
.endm

// Must set the "a" flag on the section:
// https://svnweb.freebsd.org/base/stable/11/sys/arm/arm/locore-v4.S?r1=321049&r2=321048&pathrev=321049
// https://sourceware.org/binutils/docs/as/Section.html#ELF-Version
.section .isr_vector, "a", %progbits
.global __isr_vector
__isr_vector:
// Interrupt vector as defined by Cortex-M, starting with the stack top.
// On reset, SP is initialized with *0x0 and PC is loaded with *0x4, loading
// _stack_top and Reset_Handler.
.long _stack_top
.long Reset_Handler
.long NMI_Handler
.long HardFault_Handler
.long MemoryManagement_Handler
.long BusFault_Handler
.long UsageFault_Handler
.long 0
.long 0
.long 0
.long 0
.long SVC_Handler
.long DebugMon_Handler
.long 0
.long PendSV_Handler
.long SysTick_Handler

// Extra interrupts for peripherals defined by the hardware vendor.

// Define default implementations for interrupts, redirecting to
// Default_Handler when not implemented.
IRQ NMI_Handler
IRQ HardFault_Handler
IRQ MemoryManagement_Handler
IRQ BusFault_Handler
IRQ UsageFault_Handler
IRQ SVC_Handler
IRQ DebugMon_Handler
IRQ PendSV_Handler
IRQ SysTick_Handler

.size __isr_vector, .-__isr_vector
10 changes: 10 additions & 0 deletions src/machine/machine_6502.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build cortexm

package machine

import "device/mos"

// CPUReset performs a hard system reset.
func CPUReset() {
mos.Device()
}
8 changes: 8 additions & 0 deletions src/runtime/arch_mos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build tinygo.mos

package runtime

const GOARCH = "mos" // riscv pretends to be arm

// The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 8
31 changes: 31 additions & 0 deletions src/runtime/interrupt/interrupt_6502.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build mos

package interrupt

// 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 0
}

// 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) {}

// In returns whether the system is currently in an interrupt.
func In() bool {
// There are no interrupts, so it can't be in one.
return false
}
44 changes: 44 additions & 0 deletions src/runtime/runtime_6502.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//go:build 6502

package runtime

// timeUnit in nanoseconds
type timeUnit int64

func putchar(c byte) {
}

func getchar() byte {
// dummy, TODO
return 0
}

func buffered() int {
// dummy, TODO
return 0
}

func ticks() timeUnit {
return 0
}

func sleepTicks(d timeUnit) {
return
}

func ticksToNanoseconds(ticks timeUnit) int64 {
return 0
}

func nanosecondsToTicks(ns int64) timeUnit {
return 0
}
func exit(code int) {
abort()
}

func abort() {
// TODO
for {
}
}
10 changes: 10 additions & 0 deletions targets/6502.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"llvm-target": "mos",
"build-tags": ["mos", "baremetal", "6502", "linux"],
"goos": "linux",
"linker": "ld.lld",
"gc": "conservative",
"cflags": [
"-Werror"
]
}