Skip to content

Commit

Permalink
runtime: add support for openbsd/ppc64
Browse files Browse the repository at this point in the history
Add runtime support for the openbsd/ppc64 port.

Updates #56001

Change-Id: I3cf010b34f96ce269858b02f16481fdad2cd5b77
Reviewed-on: https://go-review.googlesource.com/c/go/+/475618
Reviewed-by: Bryan Mills <[email protected]>
Reviewed-by: Paul Murphy <[email protected]>
Run-TryBot: Joel Sing <[email protected]>
Reviewed-by: Lynn Boger <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Dmitri Shuralyov <[email protected]>
Reviewed-by: Eric Grosse <[email protected]>
  • Loading branch information
4a6f656c committed Aug 22, 2023
1 parent b291538 commit c140105
Show file tree
Hide file tree
Showing 9 changed files with 985 additions and 2 deletions.
39 changes: 39 additions & 0 deletions src/runtime/asm_ppc64x.s
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,43 @@ TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
#define asmcgocallSaveOffset cgoCalleeStackSize
#endif

// func asmcgocall_no_g(fn, arg unsafe.Pointer)
// Call fn(arg) aligned appropriately for the gcc ABI.
// Called on a system stack, and there may be no g yet (during needm).
TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
MOVD fn+0(FP), R3
MOVD arg+8(FP), R4

MOVD R1, R15
SUB $(asmcgocallSaveOffset+8), R1
RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
MOVD R15, asmcgocallSaveOffset(R1)

MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?)

// This is a "global call", so put the global entry point in r12
MOVD R3, R12

#ifdef GO_PPC64X_HAS_FUNCDESC
// Load the real entry address from the first slot of the function descriptor.
MOVD 8(R12), R2
MOVD (R12), R12
#endif
MOVD R12, CTR
MOVD R4, R3 // arg in r3
BL (CTR)

// C code can clobber R0, so set it back to 0. F27-F31 are
// callee save, so we don't need to recover those.
XOR R0, R0

MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer.
#ifndef GOOS_aix
MOVD 24(R1), R2
#endif

RET

// func asmcgocall(fn, arg unsafe.Pointer) int32
// Call fn(arg) on the scheduler stack,
// aligned appropriately for the gcc ABI.
Expand Down Expand Up @@ -677,9 +714,11 @@ TEXT ·cgocallback(SB),NOSPLIT,$24-24

loadg:
// Load m and g from thread-local storage.
#ifndef GOOS_openbsd
MOVBZ runtime·iscgo(SB), R3
CMP R3, $0
BEQ nocgo
#endif
BL runtime·load_g(SB)
nocgo:

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/crash_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestCrashDumpsAllThreads(t *testing.T) {
t.Skipf("skipping; not supported on %v", runtime.GOOS)
}

if runtime.GOOS == "openbsd" && (runtime.GOARCH == "arm" || runtime.GOARCH == "mips64") {
if runtime.GOOS == "openbsd" && (runtime.GOARCH == "arm" || runtime.GOARCH == "mips64" || runtime.GOARCH == "ppc64") {
// This may be ncpu < 2 related...
t.Skipf("skipping; test fails on %s/%s - see issue #42464", runtime.GOOS, runtime.GOARCH)
}
Expand Down
183 changes: 183 additions & 0 deletions src/runtime/defs_openbsd_ppc64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// Copyright 2023 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.

// Generated from:
//
// GOARCH=ppc64 go tool cgo -godefs defs_openbsd.go
//
// Then converted to the form used by the runtime.

package runtime

import "unsafe"

const (
_EINTR = 0x4
_EFAULT = 0xe
_EAGAIN = 0x23

_O_WRONLY = 0x1
_O_NONBLOCK = 0x4
_O_CREAT = 0x200
_O_TRUNC = 0x400
_O_CLOEXEC = 0x10000

_PROT_NONE = 0x0
_PROT_READ = 0x1
_PROT_WRITE = 0x2
_PROT_EXEC = 0x4

_MAP_ANON = 0x1000
_MAP_PRIVATE = 0x2
_MAP_FIXED = 0x10
_MAP_STACK = 0x4000

_MADV_DONTNEED = 0x4
_MADV_FREE = 0x6

_SA_SIGINFO = 0x40
_SA_RESTART = 0x2
_SA_ONSTACK = 0x1

_PTHREAD_CREATE_DETACHED = 0x1

_SIGHUP = 0x1
_SIGINT = 0x2
_SIGQUIT = 0x3
_SIGILL = 0x4
_SIGTRAP = 0x5
_SIGABRT = 0x6
_SIGEMT = 0x7
_SIGFPE = 0x8
_SIGKILL = 0x9
_SIGBUS = 0xa
_SIGSEGV = 0xb
_SIGSYS = 0xc
_SIGPIPE = 0xd
_SIGALRM = 0xe
_SIGTERM = 0xf
_SIGURG = 0x10
_SIGSTOP = 0x11
_SIGTSTP = 0x12
_SIGCONT = 0x13
_SIGCHLD = 0x14
_SIGTTIN = 0x15
_SIGTTOU = 0x16
_SIGIO = 0x17
_SIGXCPU = 0x18
_SIGXFSZ = 0x19
_SIGVTALRM = 0x1a
_SIGPROF = 0x1b
_SIGWINCH = 0x1c
_SIGINFO = 0x1d
_SIGUSR1 = 0x1e
_SIGUSR2 = 0x1f

_FPE_INTDIV = 0x1
_FPE_INTOVF = 0x2
_FPE_FLTDIV = 0x3
_FPE_FLTOVF = 0x4
_FPE_FLTUND = 0x5
_FPE_FLTRES = 0x6
_FPE_FLTINV = 0x7
_FPE_FLTSUB = 0x8

_BUS_ADRALN = 0x1
_BUS_ADRERR = 0x2
_BUS_OBJERR = 0x3

_SEGV_MAPERR = 0x1
_SEGV_ACCERR = 0x2

_ITIMER_REAL = 0x0
_ITIMER_VIRTUAL = 0x1
_ITIMER_PROF = 0x2

_EV_ADD = 0x1
_EV_DELETE = 0x2
_EV_CLEAR = 0x20
_EV_ERROR = 0x4000
_EV_EOF = 0x8000
_EVFILT_READ = -0x1
_EVFILT_WRITE = -0x2
)

type tforkt struct {
tf_tcb unsafe.Pointer
tf_tid *int32
tf_stack uintptr
}

type sigcontext struct {
sc_cookie uint64
sc_mask int32
sc_reg [32]uint64
sc_lr uint64
sc_cr uint64
sc_xer uint64
sc_ctr uint64
sc_pc uint64
sc_ps uint64
sc_vrsave uint64
pad_cgo_0 [8]byte
sc_vsx [64][16]uint8
sc_fpscr uint64
sc_vscr uint64
}

type siginfo struct {
si_signo int32
si_code int32
si_errno int32
pad_cgo_0 [4]byte
_data [120]byte
}

type stackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}

type timespec struct {
tv_sec int64
tv_nsec int64
}

//go:nosplit
func (ts *timespec) setNsec(ns int64) {
ts.tv_sec = ns / 1e9
ts.tv_nsec = ns % 1e9
}

type timeval struct {
tv_sec int64
tv_usec int64
}

func (tv *timeval) set_usec(x int32) {
tv.tv_usec = int64(x)
}

type itimerval struct {
it_interval timeval
it_value timeval
}

type keventt struct {
ident uint64
filter int16
flags uint16
fflags uint32
data int64
udata *byte
}

type pthread uintptr
type pthreadattr uintptr
type pthreadcond uintptr
type pthreadcondattr uintptr
type pthreadmutex uintptr
type pthreadmutexattr uintptr
16 changes: 16 additions & 0 deletions src/runtime/rt0_openbsd_ppc64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2023 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.

#include "textflag.h"

TEXT _rt0_ppc64_openbsd(SB),NOSPLIT,$0
BR main(SB)

TEXT main(SB),NOSPLIT,$-8
// Make sure R0 is zero before _main
XOR R0, R0

MOVD $runtime·rt0_go(SB), R12
MOVD R12, CTR
BR (CTR)
83 changes: 83 additions & 0 deletions src/runtime/signal_openbsd_ppc64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2023 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.

package runtime

import (
"internal/goarch"
"unsafe"
)

type sigctxt struct {
info *siginfo
ctxt unsafe.Pointer
}

//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(c.ctxt)
}

func (c *sigctxt) r0() uint64 { return c.regs().sc_reg[0] }
func (c *sigctxt) r1() uint64 { return c.regs().sc_reg[1] }
func (c *sigctxt) r2() uint64 { return c.regs().sc_reg[2] }
func (c *sigctxt) r3() uint64 { return c.regs().sc_reg[3] }
func (c *sigctxt) r4() uint64 { return c.regs().sc_reg[4] }
func (c *sigctxt) r5() uint64 { return c.regs().sc_reg[5] }
func (c *sigctxt) r6() uint64 { return c.regs().sc_reg[6] }
func (c *sigctxt) r7() uint64 { return c.regs().sc_reg[7] }
func (c *sigctxt) r8() uint64 { return c.regs().sc_reg[8] }
func (c *sigctxt) r9() uint64 { return c.regs().sc_reg[9] }
func (c *sigctxt) r10() uint64 { return c.regs().sc_reg[10] }
func (c *sigctxt) r11() uint64 { return c.regs().sc_reg[11] }
func (c *sigctxt) r12() uint64 { return c.regs().sc_reg[12] }
func (c *sigctxt) r13() uint64 { return c.regs().sc_reg[13] }
func (c *sigctxt) r14() uint64 { return c.regs().sc_reg[14] }
func (c *sigctxt) r15() uint64 { return c.regs().sc_reg[15] }
func (c *sigctxt) r16() uint64 { return c.regs().sc_reg[16] }
func (c *sigctxt) r17() uint64 { return c.regs().sc_reg[17] }
func (c *sigctxt) r18() uint64 { return c.regs().sc_reg[18] }
func (c *sigctxt) r19() uint64 { return c.regs().sc_reg[19] }
func (c *sigctxt) r20() uint64 { return c.regs().sc_reg[20] }
func (c *sigctxt) r21() uint64 { return c.regs().sc_reg[21] }
func (c *sigctxt) r22() uint64 { return c.regs().sc_reg[22] }
func (c *sigctxt) r23() uint64 { return c.regs().sc_reg[23] }
func (c *sigctxt) r24() uint64 { return c.regs().sc_reg[24] }
func (c *sigctxt) r25() uint64 { return c.regs().sc_reg[25] }
func (c *sigctxt) r26() uint64 { return c.regs().sc_reg[26] }
func (c *sigctxt) r27() uint64 { return c.regs().sc_reg[27] }
func (c *sigctxt) r28() uint64 { return c.regs().sc_reg[28] }
func (c *sigctxt) r29() uint64 { return c.regs().sc_reg[29] }
func (c *sigctxt) r30() uint64 { return c.regs().sc_reg[30] }
func (c *sigctxt) r31() uint64 { return c.regs().sc_reg[31] }
func (c *sigctxt) sp() uint64 { return c.regs().sc_reg[1] }

//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().sc_pc }

func (c *sigctxt) trap() uint64 { return 0 /* XXX - c.regs().trap */ }
func (c *sigctxt) ctr() uint64 { return c.regs().sc_ctr }
func (c *sigctxt) link() uint64 { return c.regs().sc_lr }
func (c *sigctxt) xer() uint64 { return c.regs().sc_xer }
func (c *sigctxt) ccr() uint64 { return c.regs().sc_cr }

func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
func (c *sigctxt) sigaddr() uint64 {
return *(*uint64)(add(unsafe.Pointer(c.info), 16))
}
func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }

func (c *sigctxt) set_r0(x uint64) { c.regs().sc_reg[0] = x }
func (c *sigctxt) set_r12(x uint64) { c.regs().sc_reg[12] = x }
func (c *sigctxt) set_r30(x uint64) { c.regs().sc_reg[30] = x }
func (c *sigctxt) set_pc(x uint64) { c.regs().sc_pc = x }
func (c *sigctxt) set_sp(x uint64) { c.regs().sc_reg[1] = x }
func (c *sigctxt) set_link(x uint64) { c.regs().sc_lr = x }

func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
func (c *sigctxt) set_sigaddr(x uint64) {
*(*uintptr)(add(unsafe.Pointer(c.info), 2*goarch.PtrSize)) = uintptr(x)
}
2 changes: 1 addition & 1 deletion src/runtime/signal_ppc64x.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 (aix || linux) && (ppc64 || ppc64le)
//go:build (aix || linux || openbsd) && (ppc64 || ppc64le)

package runtime

Expand Down
5 changes: 5 additions & 0 deletions src/runtime/stubs_ppc64x.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@

package runtime

import "unsafe"

// Called from assembly only; declared for go vet.
func load_g()
func save_g()
func reginit()

//go:noescape
func asmcgocall_no_g(fn, arg unsafe.Pointer)

// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
func spillArgs()
Expand Down
Loading

0 comments on commit c140105

Please sign in to comment.