Skip to content

Commit

Permalink
add tamago/amd64 support (#11)
Browse files Browse the repository at this point in the history
* remove unused constant

* WiP tamago/amd64 support

* WiP tamago/amd64 support

* WiP tamago/amd64 support

* tidying

* ensure entry point consistency with other archs

* tidying

* move processor initialization outside tamago-go

* update github action

* tidying

* add GetG to tamago/amd64

* unify GOOS=tamago amd64/arm/riscv64 runtime support
  • Loading branch information
abarisani committed Dec 4, 2024
1 parent 8fddaf2 commit 349313d
Show file tree
Hide file tree
Showing 21 changed files with 586 additions and 466 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ jobs:
- name: Compile Go with all.bash
run: |
cd src ; ./all.bash
- name: Run Go distribution tests under tamago/amd64
run: |
GO_BUILDER_NAME=tamago GOOS=tamago GOARCH=amd64 ./bin/go tool dist test
- name: Run Go distribution tests under tamago/arm
run: |
GO_BUILDER_NAME=tamago GOOS=tamago GOARCH=arm ./bin/go tool dist test
Expand Down
1 change: 1 addition & 0 deletions src/cmd/dist/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,7 @@ var cgoEnabled = map[string]bool{
"plan9/amd64": false,
"plan9/arm": false,
"solaris/amd64": true,
"tamago/amd64": false,
"tamago/arm": false,
"tamago/riscv64": false,
"windows/386": true,
Expand Down
2 changes: 2 additions & 0 deletions src/internal/platform/zosarch.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/runtime/malloc.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ const (
//
// On other platforms, the user address space is contiguous
// and starts at 0, so no offset is necessary.
arenaBaseOffset = 0xffff800000000000*goarch.IsAmd64 + 0x0a00000000000000*goos.IsAix
arenaBaseOffset = 0xffff800000000000*goarch.IsAmd64*(1-goos.IsTamago) + 0x0a00000000000000*goos.IsAix
// A typed version of this constant that will make it into DWARF (for viewcore).
arenaBaseOffsetUintptr = uintptr(arenaBaseOffset)

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/mpagealloc_64bit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || (riscv64 && !tamago) || s390x
//go:build (amd64 && !tamago) || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || (riscv64 && !tamago) || s390x

package runtime

Expand Down
207 changes: 207 additions & 0 deletions src/runtime/os_tamago.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build tamago

package runtime

import (
"internal/runtime/atomic"
"unsafe"
)

// see testing.testBinary
var testBinary string

// Bloc allows to override the heap memory start address
var Bloc uintptr

// the following functions must be provided externally
func hwinit()
func printk(byte)
func getRandomData([]byte)
func initRNG()

// the following functions must be provided externally
// (but are already stubbed somewhere else in the runtime)
//func nanotime1() int64

// GetRandomData generates len(r) random bytes from the random source provided
// externally by the linked application.
func GetRandomData(r []byte) {
getRandomData(r)
}

// CallOnG0 calls a function (func(off int)) on g0 stack.
//
// The function arguments must be passed through the following registers
// (rather than on the frame pointer):
//
// * R0: fn argument (vector table offset)
// * R1: fn pointer
// * R2: size of stack area reserved for caller registers
// * R3: caller program counter
func CallOnG0()

// WakeG modifies a goroutine cached timer for time.Sleep (g.timer) to fire as
// soon as possible.
//
// The function arguments must be passed through the following registers
// (rather than on the frame pointer):
//
// * R0: G pointer
func WakeG()

// stubs for unused/unimplemented functionality
type mOS struct{}
type sigset struct{}
type gsignalStack struct{}

func goenvs() {}
func sigsave(p *sigset) {}
func msigrestore(sigmask sigset) {}
func clearSignalHandlers() {}
func sigblock(exiting bool) {}
func minit() {}
func unminit() {}
func mdestroy(mp *m) {}
func setProcessCPUProfiler(hz int32) {}
func setThreadCPUProfiler(hz int32) {}
func initsig(preinit bool) {}
func osyield() {}
func osyield_no_g() {}

// May run with m.p==nil, so write barriers are not allowed.
//
//go:nowritebarrier
func newosproc(mp *m) {
throw("newosproc: not implemented")
}

// Called to initialize a new m (including the bootstrap m).
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
func mpreinit(mp *m) {
mp.gsignal = malg(32 * 1024)
mp.gsignal.m = mp
}

func osinit() {
ncpu = 1
physPageSize = 4096

if Bloc != 0 {
bloc = Bloc
blocMax = bloc
} else {
initBloc()
}
}

func readRandom(r []byte) int {
initRNG()
getRandomData(r)
return len(r)
}

func signame(sig uint32) string {
return ""
}

//go:linkname os_sigpipe os.sigpipe
func os_sigpipe() {
throw("too many writes on closed pipe")
}

//go:nosplit
func crash() {
*(*int32)(nil) = 0
}

//go:linkname syscall
func syscall(number, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
switch number {
// SYS_WRITE
case 1:
r1 := write(a1, unsafe.Pointer(a2), int32(a3))
return uintptr(r1), 0, 0
default:
throw("unexpected syscall")
}

return
}

//go:nosplit
func write1(fd uintptr, buf unsafe.Pointer, count int32) int32 {
if fd != 1 && fd != 2 {
throw("unexpected fd, only stdout/stderr are supported")
}

c := uintptr(count)

for i := uintptr(0); i < c; i++ {
p := (*byte)(unsafe.Pointer(uintptr(buf) + i))
printk(*p)
}

return int32(c)
}

//go:linkname syscall_now syscall.now
func syscall_now() (sec int64, nsec int32) {
sec, nsec, _ = time_now()
return
}

//go:nosplit
func walltime() (sec int64, nsec int32) {
nano := nanotime()
sec = nano / 1000000000
nsec = int32(nano % 1000000000)
return
}

//go:nosplit
func usleep(us uint32) {
wake := nanotime() + int64(us)*1000
for nanotime() < wake {
}
}

//go:nosplit
func usleep_no_g(usec uint32) {
usleep(usec)
}

// Exit can be provided externally by the linked application to provide an
// implementation for runtime.exit.
var Exit func(int32)

func exit(code int32) {
if Exit != nil {
Exit(code)
}

print("exit with code ", code, " halting\n")

for {
// hang forever
}
}

func exitThread(wait *atomic.Uint32) {
// We should never reach exitThread
throw("exitThread: not implemented")
}

const preemptMSupported = false

func preemptM(mp *m) {
// No threads, so nothing to do.
}

// Stubs so tests can link correctly. These should never be called.
func open(name *byte, mode, perm int32) int32 { panic("not implemented") }
func closefd(fd int32) int32 { panic("not implemented") }
func read(fd int32, p unsafe.Pointer, n int32) int32 { panic("not implemented") }
30 changes: 30 additions & 0 deletions src/runtime/os_tamago_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build tamago && amd64

package runtime

// the following variables must be provided externally
var ramStart uint64
var ramSize uint64
var ramStackOffset uint64

// defined in asm_amd64.s
func cputicks() int64

// GetG returns the pointer to the current G and its P.
func GetG() (gp uint64, pp uint64)

// MemRegion returns the start and end addresses of the physical RAM assigned
// to the Go runtime.
func MemRegion() (start uint64, end uint64) {
return ramStart, ramStart + ramSize
}

// TextRegion returns the start and end addresses of the physical RAM
// containing the Go runtime executable instructions.
func TextRegion() (start uint64, end uint64) {
return uint64(firstmoduledata.text), uint64(firstmoduledata.etext)
}
Loading

0 comments on commit 349313d

Please sign in to comment.