feat: add MCP endpoint exposing calendar tools over Streamable HTTP
Adds a POST /mcp endpoint (github.com/modelcontextprotocol/go-sdk) with
three tools mirroring the existing /calendar logic: get_calendar_today,
get_calendar_for_date and get_holidays. Bumps go.mod to Go 1.25 (required
by the SDK) and vendors the new dependencies. Also fixes an unanchored
.gitignore rule ("domogeek") that was silently excluding all untracked
files under cmd/domogeek/.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hu8wwahgecuCGfesTKCfEd
This commit is contained in:
-3
@@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
@@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2018 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 gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
||||
//
|
||||
|
||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·syscall6(SB)
|
||||
|
||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSyscall6(SB)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2024 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 darwin && amd64 && gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctlbyname(SB)
|
||||
GLOBL ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB)
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
// 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.
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// byteOrder is a subset of encoding/binary.ByteOrder.
|
||||
type byteOrder interface {
|
||||
Uint32([]byte) uint32
|
||||
Uint64([]byte) uint64
|
||||
}
|
||||
|
||||
type littleEndian struct{}
|
||||
type bigEndian struct{}
|
||||
|
||||
func (littleEndian) Uint32(b []byte) uint32 {
|
||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
}
|
||||
|
||||
func (littleEndian) Uint64(b []byte) uint64 {
|
||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
}
|
||||
|
||||
func (bigEndian) Uint32(b []byte) uint32 {
|
||||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||
}
|
||||
|
||||
func (bigEndian) Uint64(b []byte) uint64 {
|
||||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||
}
|
||||
|
||||
// hostByteOrder returns littleEndian on little-endian machines and
|
||||
// bigEndian on big-endian machines.
|
||||
func hostByteOrder() byteOrder {
|
||||
switch runtime.GOARCH {
|
||||
case "386", "amd64", "amd64p32",
|
||||
"alpha",
|
||||
"arm", "arm64",
|
||||
"loong64",
|
||||
"mipsle", "mips64le", "mips64p32le",
|
||||
"nios2",
|
||||
"ppc64le",
|
||||
"riscv", "riscv64",
|
||||
"sh":
|
||||
return littleEndian{}
|
||||
case "armbe", "arm64be",
|
||||
"m68k",
|
||||
"mips", "mips64", "mips64p32",
|
||||
"ppc", "ppc64",
|
||||
"s390", "s390x",
|
||||
"shbe",
|
||||
"sparc", "sparc64":
|
||||
return bigEndian{}
|
||||
}
|
||||
panic("unknown architecture")
|
||||
}
|
||||
+338
@@ -0,0 +1,338 @@
|
||||
// Copyright 2018 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 cpu implements processor feature detection for
|
||||
// various CPU architectures.
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Initialized reports whether the CPU features were initialized.
|
||||
//
|
||||
// For some GOOS/GOARCH combinations initialization of the CPU features depends
|
||||
// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
|
||||
// Initialized will report false if reading the file fails.
|
||||
var Initialized bool
|
||||
|
||||
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||
|
||||
// X86 contains the supported CPU features of the
|
||||
// current X86/AMD64 platform. If the current platform
|
||||
// is not X86/AMD64 then all feature flags are false.
|
||||
//
|
||||
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||
// registers in addition to the CPUID feature bit being set.
|
||||
var X86 struct {
|
||||
_ CacheLinePad
|
||||
HasAES bool // AES hardware implementation (AES NI)
|
||||
HasADX bool // Multi-precision add-carry instruction extensions
|
||||
HasAVX bool // Advanced vector extension
|
||||
HasAVX2 bool // Advanced vector extension 2
|
||||
HasAVX512 bool // Advanced vector extension 512
|
||||
HasAVX512F bool // Advanced vector extension 512 Foundation Instructions
|
||||
HasAVX512CD bool // Advanced vector extension 512 Conflict Detection Instructions
|
||||
HasAVX512ER bool // Advanced vector extension 512 Exponential and Reciprocal Instructions
|
||||
HasAVX512PF bool // Advanced vector extension 512 Prefetch Instructions
|
||||
HasAVX512VL bool // Advanced vector extension 512 Vector Length Extensions
|
||||
HasAVX512BW bool // Advanced vector extension 512 Byte and Word Instructions
|
||||
HasAVX512DQ bool // Advanced vector extension 512 Doubleword and Quadword Instructions
|
||||
HasAVX512IFMA bool // Advanced vector extension 512 Integer Fused Multiply Add
|
||||
HasAVX512VBMI bool // Advanced vector extension 512 Vector Byte Manipulation Instructions
|
||||
HasAVX5124VNNIW bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision
|
||||
HasAVX5124FMAPS bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision
|
||||
HasAVX512VPOPCNTDQ bool // Advanced vector extension 512 Double and quad word population count instructions
|
||||
HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations
|
||||
HasAVX512VNNI bool // Advanced vector extension 512 Vector Neural Network Instructions
|
||||
HasAVX512GFNI bool // Advanced vector extension 512 Galois field New Instructions
|
||||
HasAVX512VAES bool // Advanced vector extension 512 Vector AES instructions
|
||||
HasAVX512VBMI2 bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2
|
||||
HasAVX512BITALG bool // Advanced vector extension 512 Bit Algorithms
|
||||
HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions
|
||||
HasAMXTile bool // Advanced Matrix Extension Tile instructions
|
||||
HasAMXInt8 bool // Advanced Matrix Extension Int8 instructions
|
||||
HasAMXBF16 bool // Advanced Matrix Extension BFloat16 instructions
|
||||
HasBMI1 bool // Bit manipulation instruction set 1
|
||||
HasBMI2 bool // Bit manipulation instruction set 2
|
||||
HasCX16 bool // Compare and exchange 16 Bytes
|
||||
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||
HasFMA bool // Fused-multiply-add instructions
|
||||
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||
HasSSE3 bool // Streaming SIMD extension 3
|
||||
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||
HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add
|
||||
HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions
|
||||
HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// ARM64 contains the supported CPU features of the
|
||||
// current ARMv8(aarch64) platform. If the current platform
|
||||
// is not arm64 then all feature flags are false.
|
||||
var ARM64 struct {
|
||||
_ CacheLinePad
|
||||
HasFP bool // Floating-point instruction set (always available)
|
||||
HasASIMD bool // Advanced SIMD (always available)
|
||||
HasEVTSTRM bool // Event stream support
|
||||
HasAES bool // AES hardware implementation
|
||||
HasPMULL bool // Polynomial multiplication instruction set
|
||||
HasSHA1 bool // SHA1 hardware implementation
|
||||
HasSHA2 bool // SHA2 hardware implementation
|
||||
HasCRC32 bool // CRC32 hardware implementation
|
||||
HasATOMICS bool // Atomic memory operation instruction set
|
||||
HasFPHP bool // Half precision floating-point instruction set
|
||||
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||
HasCPUID bool // CPUID identification scheme registers
|
||||
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||
HasLRCPC bool // Release Consistent processor consistent support
|
||||
HasDCPOP bool // Persistent memory support
|
||||
HasSHA3 bool // SHA3 hardware implementation
|
||||
HasSM3 bool // SM3 hardware implementation
|
||||
HasSM4 bool // SM4 hardware implementation
|
||||
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||
HasSHA512 bool // SHA512 hardware implementation
|
||||
HasSVE bool // Scalable Vector Extensions
|
||||
HasSVE2 bool // Scalable Vector Extensions 2
|
||||
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||
HasDIT bool // Data Independent Timing support
|
||||
HasI8MM bool // Advanced SIMD Int8 matrix multiplication instructions
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// ARM contains the supported CPU features of the current ARM (32-bit) platform.
|
||||
// All feature flags are false if:
|
||||
// 1. the current platform is not arm, or
|
||||
// 2. the current operating system is not Linux.
|
||||
var ARM struct {
|
||||
_ CacheLinePad
|
||||
HasSWP bool // SWP instruction support
|
||||
HasHALF bool // Half-word load and store support
|
||||
HasTHUMB bool // ARM Thumb instruction set
|
||||
Has26BIT bool // Address space limited to 26-bits
|
||||
HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support
|
||||
HasFPA bool // Floating point arithmetic support
|
||||
HasVFP bool // Vector floating point support
|
||||
HasEDSP bool // DSP Extensions support
|
||||
HasJAVA bool // Java instruction set
|
||||
HasIWMMXT bool // Intel Wireless MMX technology support
|
||||
HasCRUNCH bool // MaverickCrunch context switching and handling
|
||||
HasTHUMBEE bool // Thumb EE instruction set
|
||||
HasNEON bool // NEON instruction set
|
||||
HasVFPv3 bool // Vector floating point version 3 support
|
||||
HasVFPv3D16 bool // Vector floating point version 3 D8-D15
|
||||
HasTLS bool // Thread local storage support
|
||||
HasVFPv4 bool // Vector floating point version 4 support
|
||||
HasIDIVA bool // Integer divide instruction support in ARM mode
|
||||
HasIDIVT bool // Integer divide instruction support in Thumb mode
|
||||
HasVFPD32 bool // Vector floating point version 3 D15-D31
|
||||
HasLPAE bool // Large Physical Address Extensions
|
||||
HasEVTSTRM bool // Event stream support
|
||||
HasAES bool // AES hardware implementation
|
||||
HasPMULL bool // Polynomial multiplication instruction set
|
||||
HasSHA1 bool // SHA1 hardware implementation
|
||||
HasSHA2 bool // SHA2 hardware implementation
|
||||
HasCRC32 bool // CRC32 hardware implementation
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// The booleans in Loong64 contain the correspondingly named cpu feature bit.
|
||||
// The struct is padded to avoid false sharing.
|
||||
var Loong64 struct {
|
||||
_ CacheLinePad
|
||||
HasLSX bool // support 128-bit vector extension
|
||||
HasLASX bool // support 256-bit vector extension
|
||||
HasCRC32 bool // support CRC instruction
|
||||
HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction
|
||||
HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} instruction
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// MIPS64X contains the supported CPU features of the current mips64/mips64le
|
||||
// platforms. If the current platform is not mips64/mips64le or the current
|
||||
// operating system is not Linux then all feature flags are false.
|
||||
var MIPS64X struct {
|
||||
_ CacheLinePad
|
||||
HasMSA bool // MIPS SIMD architecture
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||
//
|
||||
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||
// since there are no optional categories. There are some exceptions that also
|
||||
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||
// those as well. The struct is padded to avoid false sharing.
|
||||
var PPC64 struct {
|
||||
_ CacheLinePad
|
||||
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||
IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// S390X contains the supported CPU features of the current IBM Z
|
||||
// (s390x) platform. If the current platform is not IBM Z then all
|
||||
// feature flags are false.
|
||||
//
|
||||
// S390X is padded to avoid false sharing. Further HasVX is only set
|
||||
// if the OS supports vector registers in addition to the STFLE
|
||||
// feature bit being set.
|
||||
var S390X struct {
|
||||
_ CacheLinePad
|
||||
HasZARCH bool // z/Architecture mode is active [mandatory]
|
||||
HasSTFLE bool // store facility list extended
|
||||
HasLDISP bool // long (20-bit) displacements
|
||||
HasEIMM bool // 32-bit immediates
|
||||
HasDFP bool // decimal floating point
|
||||
HasETF3EH bool // ETF-3 enhanced
|
||||
HasMSA bool // message security assist (CPACF)
|
||||
HasAES bool // KM-AES{128,192,256} functions
|
||||
HasAESCBC bool // KMC-AES{128,192,256} functions
|
||||
HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
||||
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
||||
HasGHASH bool // KIMD-GHASH function
|
||||
HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
||||
HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
||||
HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
||||
HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
|
||||
HasVX bool // vector facility
|
||||
HasVXE bool // vector-enhancements facility 1
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// RISCV64 contains the supported CPU features and performance characteristics for riscv64
|
||||
// platforms. The booleans in RISCV64, with the exception of HasFastMisaligned, indicate
|
||||
// the presence of RISC-V extensions.
|
||||
//
|
||||
// It is safe to assume that all the RV64G extensions are supported and so they are omitted from
|
||||
// this structure. As riscv64 Go programs require at least RV64G, the code that populates
|
||||
// this structure cannot run successfully if some of the RV64G extensions are missing.
|
||||
// The struct is padded to avoid false sharing.
|
||||
var RISCV64 struct {
|
||||
_ CacheLinePad
|
||||
HasFastMisaligned bool // Fast misaligned accesses
|
||||
HasC bool // Compressed instruction-set extension
|
||||
HasV bool // Vector extension compatible with RVV 1.0
|
||||
HasZba bool // Address generation instructions extension
|
||||
HasZbb bool // Basic bit-manipulation extension
|
||||
HasZbs bool // Single-bit instructions extension
|
||||
HasZvbb bool // Vector Basic Bit-manipulation
|
||||
HasZvbc bool // Vector Carryless Multiplication
|
||||
HasZvkb bool // Vector Cryptography Bit-manipulation
|
||||
HasZvkt bool // Vector Data-Independent Execution Latency
|
||||
HasZvkg bool // Vector GCM/GMAC
|
||||
HasZvkn bool // NIST Algorithm Suite (AES/SHA256/SHA512)
|
||||
HasZvknc bool // NIST Algorithm Suite with carryless multiply
|
||||
HasZvkng bool // NIST Algorithm Suite with GCM
|
||||
HasZvks bool // ShangMi Algorithm Suite
|
||||
HasZvksc bool // ShangMi Algorithm Suite with carryless multiplication
|
||||
HasZvksg bool // ShangMi Algorithm Suite with GCM
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
func init() {
|
||||
archInit()
|
||||
initOptions()
|
||||
processOptions()
|
||||
}
|
||||
|
||||
// options contains the cpu debug options that can be used in GODEBUG.
|
||||
// Options are arch dependent and are added by the arch specific initOptions functions.
|
||||
// Features that are mandatory for the specific GOARCH should have the Required field set
|
||||
// (e.g. SSE2 on amd64).
|
||||
var options []option
|
||||
|
||||
// Option names should be lower case. e.g. avx instead of AVX.
|
||||
type option struct {
|
||||
Name string
|
||||
Feature *bool
|
||||
Specified bool // whether feature value was specified in GODEBUG
|
||||
Enable bool // whether feature should be enabled
|
||||
Required bool // whether feature is mandatory and can not be disabled
|
||||
}
|
||||
|
||||
func processOptions() {
|
||||
env := os.Getenv("GODEBUG")
|
||||
field:
|
||||
for env != "" {
|
||||
field := ""
|
||||
i := strings.IndexByte(env, ',')
|
||||
if i < 0 {
|
||||
field, env = env, ""
|
||||
} else {
|
||||
field, env = env[:i], env[i+1:]
|
||||
}
|
||||
if len(field) < 4 || field[:4] != "cpu." {
|
||||
continue
|
||||
}
|
||||
i = strings.IndexByte(field, '=')
|
||||
if i < 0 {
|
||||
print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n")
|
||||
continue
|
||||
}
|
||||
key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
|
||||
|
||||
var enable bool
|
||||
switch value {
|
||||
case "on":
|
||||
enable = true
|
||||
case "off":
|
||||
enable = false
|
||||
default:
|
||||
print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
|
||||
continue field
|
||||
}
|
||||
|
||||
if key == "all" {
|
||||
for i := range options {
|
||||
options[i].Specified = true
|
||||
options[i].Enable = enable || options[i].Required
|
||||
}
|
||||
continue field
|
||||
}
|
||||
|
||||
for i := range options {
|
||||
if options[i].Name == key {
|
||||
options[i].Specified = true
|
||||
options[i].Enable = enable
|
||||
continue field
|
||||
}
|
||||
}
|
||||
|
||||
print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n")
|
||||
}
|
||||
|
||||
for _, o := range options {
|
||||
if !o.Specified {
|
||||
continue
|
||||
}
|
||||
|
||||
if o.Enable && !*o.Feature {
|
||||
print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n")
|
||||
continue
|
||||
}
|
||||
|
||||
if !o.Enable && o.Required {
|
||||
print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n")
|
||||
continue
|
||||
}
|
||||
|
||||
*o.Feature = o.Enable
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// 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 aix
|
||||
|
||||
package cpu
|
||||
|
||||
const (
|
||||
// getsystemcfg constants
|
||||
_SC_IMPL = 2
|
||||
_IMPL_POWER8 = 0x10000
|
||||
_IMPL_POWER9 = 0x20000
|
||||
)
|
||||
|
||||
func archInit() {
|
||||
impl := getsystemcfg(_SC_IMPL)
|
||||
if impl&_IMPL_POWER8 != 0 {
|
||||
PPC64.IsPOWER8 = true
|
||||
}
|
||||
if impl&_IMPL_POWER9 != 0 {
|
||||
PPC64.IsPOWER8 = true
|
||||
PPC64.IsPOWER9 = true
|
||||
}
|
||||
|
||||
Initialized = true
|
||||
}
|
||||
|
||||
func getsystemcfg(label int) (n uint64) {
|
||||
r0, _ := callgetsystemcfg(label)
|
||||
n = uint64(r0)
|
||||
return
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// Copyright 2018 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 cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
// HWCAP/HWCAP2 bits.
|
||||
// These are specific to Linux.
|
||||
const (
|
||||
hwcap_SWP = 1 << 0
|
||||
hwcap_HALF = 1 << 1
|
||||
hwcap_THUMB = 1 << 2
|
||||
hwcap_26BIT = 1 << 3
|
||||
hwcap_FAST_MULT = 1 << 4
|
||||
hwcap_FPA = 1 << 5
|
||||
hwcap_VFP = 1 << 6
|
||||
hwcap_EDSP = 1 << 7
|
||||
hwcap_JAVA = 1 << 8
|
||||
hwcap_IWMMXT = 1 << 9
|
||||
hwcap_CRUNCH = 1 << 10
|
||||
hwcap_THUMBEE = 1 << 11
|
||||
hwcap_NEON = 1 << 12
|
||||
hwcap_VFPv3 = 1 << 13
|
||||
hwcap_VFPv3D16 = 1 << 14
|
||||
hwcap_TLS = 1 << 15
|
||||
hwcap_VFPv4 = 1 << 16
|
||||
hwcap_IDIVA = 1 << 17
|
||||
hwcap_IDIVT = 1 << 18
|
||||
hwcap_VFPD32 = 1 << 19
|
||||
hwcap_LPAE = 1 << 20
|
||||
hwcap_EVTSTRM = 1 << 21
|
||||
|
||||
hwcap2_AES = 1 << 0
|
||||
hwcap2_PMULL = 1 << 1
|
||||
hwcap2_SHA1 = 1 << 2
|
||||
hwcap2_SHA2 = 1 << 3
|
||||
hwcap2_CRC32 = 1 << 4
|
||||
)
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "pmull", Feature: &ARM.HasPMULL},
|
||||
{Name: "sha1", Feature: &ARM.HasSHA1},
|
||||
{Name: "sha2", Feature: &ARM.HasSHA2},
|
||||
{Name: "swp", Feature: &ARM.HasSWP},
|
||||
{Name: "thumb", Feature: &ARM.HasTHUMB},
|
||||
{Name: "thumbee", Feature: &ARM.HasTHUMBEE},
|
||||
{Name: "tls", Feature: &ARM.HasTLS},
|
||||
{Name: "vfp", Feature: &ARM.HasVFP},
|
||||
{Name: "vfpd32", Feature: &ARM.HasVFPD32},
|
||||
{Name: "vfpv3", Feature: &ARM.HasVFPv3},
|
||||
{Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16},
|
||||
{Name: "vfpv4", Feature: &ARM.HasVFPv4},
|
||||
{Name: "half", Feature: &ARM.HasHALF},
|
||||
{Name: "26bit", Feature: &ARM.Has26BIT},
|
||||
{Name: "fastmul", Feature: &ARM.HasFASTMUL},
|
||||
{Name: "fpa", Feature: &ARM.HasFPA},
|
||||
{Name: "edsp", Feature: &ARM.HasEDSP},
|
||||
{Name: "java", Feature: &ARM.HasJAVA},
|
||||
{Name: "iwmmxt", Feature: &ARM.HasIWMMXT},
|
||||
{Name: "crunch", Feature: &ARM.HasCRUNCH},
|
||||
{Name: "neon", Feature: &ARM.HasNEON},
|
||||
{Name: "idivt", Feature: &ARM.HasIDIVT},
|
||||
{Name: "idiva", Feature: &ARM.HasIDIVA},
|
||||
{Name: "lpae", Feature: &ARM.HasLPAE},
|
||||
{Name: "evtstrm", Feature: &ARM.HasEVTSTRM},
|
||||
{Name: "aes", Feature: &ARM.HasAES},
|
||||
{Name: "crc32", Feature: &ARM.HasCRC32},
|
||||
}
|
||||
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
// 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.
|
||||
|
||||
package cpu
|
||||
|
||||
import "runtime"
|
||||
|
||||
// cacheLineSize is used to prevent false sharing of cache lines.
|
||||
// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
|
||||
// It doesn't cost much and is much more future-proof.
|
||||
const cacheLineSize = 128
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "fp", Feature: &ARM64.HasFP},
|
||||
{Name: "asimd", Feature: &ARM64.HasASIMD},
|
||||
{Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
|
||||
{Name: "aes", Feature: &ARM64.HasAES},
|
||||
{Name: "fphp", Feature: &ARM64.HasFPHP},
|
||||
{Name: "jscvt", Feature: &ARM64.HasJSCVT},
|
||||
{Name: "lrcpc", Feature: &ARM64.HasLRCPC},
|
||||
{Name: "pmull", Feature: &ARM64.HasPMULL},
|
||||
{Name: "sha1", Feature: &ARM64.HasSHA1},
|
||||
{Name: "sha2", Feature: &ARM64.HasSHA2},
|
||||
{Name: "sha3", Feature: &ARM64.HasSHA3},
|
||||
{Name: "sha512", Feature: &ARM64.HasSHA512},
|
||||
{Name: "sm3", Feature: &ARM64.HasSM3},
|
||||
{Name: "sm4", Feature: &ARM64.HasSM4},
|
||||
{Name: "sve", Feature: &ARM64.HasSVE},
|
||||
{Name: "sve2", Feature: &ARM64.HasSVE2},
|
||||
{Name: "crc32", Feature: &ARM64.HasCRC32},
|
||||
{Name: "atomics", Feature: &ARM64.HasATOMICS},
|
||||
{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
|
||||
{Name: "cpuid", Feature: &ARM64.HasCPUID},
|
||||
{Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
|
||||
{Name: "fcma", Feature: &ARM64.HasFCMA},
|
||||
{Name: "dcpop", Feature: &ARM64.HasDCPOP},
|
||||
{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
|
||||
{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
|
||||
{Name: "dit", Feature: &ARM64.HasDIT},
|
||||
{Name: "i8mm", Feature: &ARM64.HasI8MM},
|
||||
}
|
||||
}
|
||||
|
||||
func archInit() {
|
||||
switch runtime.GOOS {
|
||||
case "freebsd":
|
||||
readARM64Registers()
|
||||
case "linux", "netbsd", "openbsd", "windows":
|
||||
doinit()
|
||||
default:
|
||||
// Many platforms don't seem to allow reading these registers.
|
||||
setMinimalFeatures()
|
||||
}
|
||||
}
|
||||
|
||||
// setMinimalFeatures fakes the minimal ARM64 features expected by
|
||||
// TestARM64minimalFeatures.
|
||||
func setMinimalFeatures() {
|
||||
ARM64.HasASIMD = true
|
||||
ARM64.HasFP = true
|
||||
}
|
||||
|
||||
func readARM64Registers() {
|
||||
Initialized = true
|
||||
|
||||
parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
|
||||
}
|
||||
|
||||
func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
|
||||
// ID_AA64ISAR0_EL1
|
||||
switch extractBits(isar0, 4, 7) {
|
||||
case 1:
|
||||
ARM64.HasAES = true
|
||||
case 2:
|
||||
ARM64.HasAES = true
|
||||
ARM64.HasPMULL = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 8, 11) {
|
||||
case 1:
|
||||
ARM64.HasSHA1 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 12, 15) {
|
||||
case 1:
|
||||
ARM64.HasSHA2 = true
|
||||
case 2:
|
||||
ARM64.HasSHA2 = true
|
||||
ARM64.HasSHA512 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 16, 19) {
|
||||
case 1:
|
||||
ARM64.HasCRC32 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 20, 23) {
|
||||
case 2:
|
||||
ARM64.HasATOMICS = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 28, 31) {
|
||||
case 1:
|
||||
ARM64.HasASIMDRDM = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 32, 35) {
|
||||
case 1:
|
||||
ARM64.HasSHA3 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 36, 39) {
|
||||
case 1:
|
||||
ARM64.HasSM3 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 40, 43) {
|
||||
case 1:
|
||||
ARM64.HasSM4 = true
|
||||
}
|
||||
|
||||
switch extractBits(isar0, 44, 47) {
|
||||
case 1:
|
||||
ARM64.HasASIMDDP = true
|
||||
}
|
||||
|
||||
// ID_AA64ISAR1_EL1
|
||||
switch extractBits(isar1, 0, 3) {
|
||||
case 1:
|
||||
ARM64.HasDCPOP = true
|
||||
}
|
||||
|
||||
switch extractBits(isar1, 12, 15) {
|
||||
case 1:
|
||||
ARM64.HasJSCVT = true
|
||||
}
|
||||
|
||||
switch extractBits(isar1, 16, 19) {
|
||||
case 1:
|
||||
ARM64.HasFCMA = true
|
||||
}
|
||||
|
||||
switch extractBits(isar1, 20, 23) {
|
||||
case 1:
|
||||
ARM64.HasLRCPC = true
|
||||
}
|
||||
|
||||
switch extractBits(isar1, 52, 55) {
|
||||
case 1:
|
||||
ARM64.HasI8MM = true
|
||||
}
|
||||
|
||||
// ID_AA64PFR0_EL1
|
||||
switch extractBits(pfr0, 16, 19) {
|
||||
case 0:
|
||||
ARM64.HasFP = true
|
||||
case 1:
|
||||
ARM64.HasFP = true
|
||||
ARM64.HasFPHP = true
|
||||
}
|
||||
|
||||
switch extractBits(pfr0, 20, 23) {
|
||||
case 0:
|
||||
ARM64.HasASIMD = true
|
||||
case 1:
|
||||
ARM64.HasASIMD = true
|
||||
ARM64.HasASIMDHP = true
|
||||
}
|
||||
|
||||
switch extractBits(pfr0, 32, 35) {
|
||||
case 1:
|
||||
ARM64.HasSVE = true
|
||||
|
||||
parseARM64SVERegister(getzfr0())
|
||||
}
|
||||
|
||||
switch extractBits(pfr0, 48, 51) {
|
||||
case 1:
|
||||
ARM64.HasDIT = true
|
||||
}
|
||||
}
|
||||
|
||||
func parseARM64SVERegister(zfr0 uint64) {
|
||||
switch extractBits(zfr0, 0, 3) {
|
||||
case 1:
|
||||
ARM64.HasSVE2 = true
|
||||
}
|
||||
}
|
||||
|
||||
func extractBits(data uint64, start, end uint) uint {
|
||||
return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// 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 gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func getisar0() uint64
|
||||
TEXT ·getisar0(SB),NOSPLIT,$0-8
|
||||
// get Instruction Set Attributes 0 into x0
|
||||
MRS ID_AA64ISAR0_EL1, R0
|
||||
MOVD R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func getisar1() uint64
|
||||
TEXT ·getisar1(SB),NOSPLIT,$0-8
|
||||
// get Instruction Set Attributes 1 into x0
|
||||
MRS ID_AA64ISAR1_EL1, R0
|
||||
MOVD R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func getpfr0() uint64
|
||||
TEXT ·getpfr0(SB),NOSPLIT,$0-8
|
||||
// get Processor Feature Register 0 into x0
|
||||
MRS ID_AA64PFR0_EL1, R0
|
||||
MOVD R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func getzfr0() uint64
|
||||
TEXT ·getzfr0(SB),NOSPLIT,$0-8
|
||||
// get SVE Feature Register 0 into x0
|
||||
MRS ID_AA64ZFR0_EL1, R0
|
||||
MOVD R0, ret+0(FP)
|
||||
RET
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright 2024 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 darwin && amd64 && gc
|
||||
|
||||
package cpu
|
||||
|
||||
// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl
|
||||
// call (see issue 43089). It also restricts AVX512 support for Darwin to
|
||||
// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233).
|
||||
//
|
||||
// Background:
|
||||
// Darwin implements a special mechanism to economize on thread state when
|
||||
// AVX512 specific registers are not in use. This scheme minimizes state when
|
||||
// preempting threads that haven't yet used any AVX512 instructions, but adds
|
||||
// special requirements to check for AVX512 hardware support at runtime (e.g.
|
||||
// via sysctl call or commpage inspection). See issue 43089 and link below for
|
||||
// full background:
|
||||
// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240
|
||||
//
|
||||
// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0
|
||||
// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption
|
||||
// of the AVX512 mask registers (K0-K7) upon signal return. For this reason
|
||||
// AVX512 is considered unsafe to use on Darwin for kernel versions prior to
|
||||
// 21.3.0, where a fix has been confirmed. See issue 49233 for full background.
|
||||
func darwinSupportsAVX512() bool {
|
||||
return darwinSysctlEnabled([]byte("hw.optional.avx512f\x00")) && darwinKernelVersionCheck(21, 3, 0)
|
||||
}
|
||||
|
||||
// Ensure Darwin kernel version is at least major.minor.patch, avoiding dependencies
|
||||
func darwinKernelVersionCheck(major, minor, patch int) bool {
|
||||
var release [256]byte
|
||||
err := darwinOSRelease(&release)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var mmp [3]int
|
||||
c := 0
|
||||
Loop:
|
||||
for _, b := range release[:] {
|
||||
switch {
|
||||
case b >= '0' && b <= '9':
|
||||
mmp[c] = 10*mmp[c] + int(b-'0')
|
||||
case b == '.':
|
||||
c++
|
||||
if c > 2 {
|
||||
return false
|
||||
}
|
||||
case b == 0:
|
||||
break Loop
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
if c != 2 {
|
||||
return false
|
||||
}
|
||||
return mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] == minor && mmp[2] >= patch)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// 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 gc
|
||||
|
||||
package cpu
|
||||
|
||||
func getisar0() uint64
|
||||
func getisar1() uint64
|
||||
func getpfr0() uint64
|
||||
func getzfr0() uint64
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// 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 gc
|
||||
|
||||
package cpu
|
||||
|
||||
// haveAsmFunctions reports whether the other functions in this file can
|
||||
// be safely called.
|
||||
func haveAsmFunctions() bool { return true }
|
||||
|
||||
// The following feature detection functions are defined in cpu_s390x.s.
|
||||
// They are likely to be expensive to call so the results should be cached.
|
||||
func stfle() facilityList
|
||||
func kmQuery() queryResult
|
||||
func kmcQuery() queryResult
|
||||
func kmctrQuery() queryResult
|
||||
func kmaQuery() queryResult
|
||||
func kimdQuery() queryResult
|
||||
func klmdQuery() queryResult
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// Copyright 2018 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 (386 || amd64 || amd64p32) && gc
|
||||
|
||||
package cpu
|
||||
|
||||
// cpuid is implemented in cpu_gc_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in cpu_gc_x86.s for gc compiler
|
||||
// and in cpu_gccgo.c for gccgo.
|
||||
func xgetbv() (eax, edx uint32)
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 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 (386 || amd64 || amd64p32) && gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuid(SB), NOSPLIT, $0-24
|
||||
MOVL eaxArg+0(FP), AX
|
||||
MOVL ecxArg+4(FP), CX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func xgetbv() (eax, edx uint32)
|
||||
TEXT ·xgetbv(SB), NOSPLIT, $0-8
|
||||
MOVL $0, CX
|
||||
XGETBV
|
||||
MOVL AX, eax+0(FP)
|
||||
MOVL DX, edx+4(FP)
|
||||
RET
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// 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 gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
func getisar0() uint64 { return 0 }
|
||||
func getisar1() uint64 { return 0 }
|
||||
func getpfr0() uint64 { return 0 }
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// 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 gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
// haveAsmFunctions reports whether the other functions in this file can
|
||||
// be safely called.
|
||||
func haveAsmFunctions() bool { return false }
|
||||
|
||||
// TODO(mundaym): the following feature detection functions are currently
|
||||
// stubs. See https://golang.org/cl/162887 for how to fix this.
|
||||
// They are likely to be expensive to call so the results should be cached.
|
||||
func stfle() facilityList { panic("not implemented for gccgo") }
|
||||
func kmQuery() queryResult { panic("not implemented for gccgo") }
|
||||
func kmcQuery() queryResult { panic("not implemented for gccgo") }
|
||||
func kmctrQuery() queryResult { panic("not implemented for gccgo") }
|
||||
func kmaQuery() queryResult { panic("not implemented for gccgo") }
|
||||
func kimdQuery() queryResult { panic("not implemented for gccgo") }
|
||||
func klmdQuery() queryResult { panic("not implemented for gccgo") }
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// Copyright 2018 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 (386 || amd64 || amd64p32) && gccgo
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <stdint.h>
|
||||
#include <x86intrin.h>
|
||||
|
||||
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||
int
|
||||
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("xsave")
|
||||
#pragma clang attribute push (__attribute__((target("xsave"))), apply_to=function)
|
||||
|
||||
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||
// specified in the ECX register into registers EDX:EAX.
|
||||
// Currently, the only supported value for XCR is 0.
|
||||
void
|
||||
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||
{
|
||||
uint64_t v = _xgetbv(0);
|
||||
*eax = v & 0xffffffff;
|
||||
*edx = v >> 32;
|
||||
}
|
||||
|
||||
#pragma clang attribute pop
|
||||
#pragma GCC pop_options
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 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 (386 || amd64 || amd64p32) && gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
//extern gccgoGetCpuidCount
|
||||
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||
var a, b, c, d uint32
|
||||
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||
return a, b, c, d
|
||||
}
|
||||
|
||||
//extern gccgoXgetbv
|
||||
func gccgoXgetbv(eax, edx *uint32)
|
||||
|
||||
func xgetbv() (eax, edx uint32) {
|
||||
var a, d uint32
|
||||
gccgoXgetbv(&a, &d)
|
||||
return a, d
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// Copyright 2018 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 !386 && !amd64 && !amd64p32 && !arm64
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {
|
||||
if err := readHWCAP(); err != nil {
|
||||
return
|
||||
}
|
||||
doinit()
|
||||
Initialized = true
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
package cpu
|
||||
|
||||
func doinit() {
|
||||
ARM.HasSWP = isSet(hwCap, hwcap_SWP)
|
||||
ARM.HasHALF = isSet(hwCap, hwcap_HALF)
|
||||
ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB)
|
||||
ARM.Has26BIT = isSet(hwCap, hwcap_26BIT)
|
||||
ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT)
|
||||
ARM.HasFPA = isSet(hwCap, hwcap_FPA)
|
||||
ARM.HasVFP = isSet(hwCap, hwcap_VFP)
|
||||
ARM.HasEDSP = isSet(hwCap, hwcap_EDSP)
|
||||
ARM.HasJAVA = isSet(hwCap, hwcap_JAVA)
|
||||
ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT)
|
||||
ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH)
|
||||
ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE)
|
||||
ARM.HasNEON = isSet(hwCap, hwcap_NEON)
|
||||
ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3)
|
||||
ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16)
|
||||
ARM.HasTLS = isSet(hwCap, hwcap_TLS)
|
||||
ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4)
|
||||
ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA)
|
||||
ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT)
|
||||
ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32)
|
||||
ARM.HasLPAE = isSet(hwCap, hwcap_LPAE)
|
||||
ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||
ARM.HasAES = isSet(hwCap2, hwcap2_AES)
|
||||
ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL)
|
||||
ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1)
|
||||
ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2)
|
||||
ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
// Copyright 2018 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 cpu
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||
const (
|
||||
hwcap_FP = 1 << 0
|
||||
hwcap_ASIMD = 1 << 1
|
||||
hwcap_EVTSTRM = 1 << 2
|
||||
hwcap_AES = 1 << 3
|
||||
hwcap_PMULL = 1 << 4
|
||||
hwcap_SHA1 = 1 << 5
|
||||
hwcap_SHA2 = 1 << 6
|
||||
hwcap_CRC32 = 1 << 7
|
||||
hwcap_ATOMICS = 1 << 8
|
||||
hwcap_FPHP = 1 << 9
|
||||
hwcap_ASIMDHP = 1 << 10
|
||||
hwcap_CPUID = 1 << 11
|
||||
hwcap_ASIMDRDM = 1 << 12
|
||||
hwcap_JSCVT = 1 << 13
|
||||
hwcap_FCMA = 1 << 14
|
||||
hwcap_LRCPC = 1 << 15
|
||||
hwcap_DCPOP = 1 << 16
|
||||
hwcap_SHA3 = 1 << 17
|
||||
hwcap_SM3 = 1 << 18
|
||||
hwcap_SM4 = 1 << 19
|
||||
hwcap_ASIMDDP = 1 << 20
|
||||
hwcap_SHA512 = 1 << 21
|
||||
hwcap_SVE = 1 << 22
|
||||
hwcap_ASIMDFHM = 1 << 23
|
||||
hwcap_DIT = 1 << 24
|
||||
|
||||
hwcap2_SVE2 = 1 << 1
|
||||
hwcap2_I8MM = 1 << 13
|
||||
)
|
||||
|
||||
// linuxKernelCanEmulateCPUID reports whether we're running
|
||||
// on Linux 4.11+. Ideally we'd like to ask the question about
|
||||
// whether the current kernel contains
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77c97b4ee21290f5f083173d957843b615abbff2
|
||||
// but the version number will have to do.
|
||||
func linuxKernelCanEmulateCPUID() bool {
|
||||
var un syscall.Utsname
|
||||
syscall.Uname(&un)
|
||||
var sb strings.Builder
|
||||
for _, b := range un.Release[:] {
|
||||
if b == 0 {
|
||||
break
|
||||
}
|
||||
sb.WriteByte(byte(b))
|
||||
}
|
||||
major, minor, _, ok := parseRelease(sb.String())
|
||||
return ok && (major > 4 || major == 4 && minor >= 11)
|
||||
}
|
||||
|
||||
func doinit() {
|
||||
if err := readHWCAP(); err != nil {
|
||||
// We failed to read /proc/self/auxv. This can happen if the binary has
|
||||
// been given extra capabilities(7) with /bin/setcap.
|
||||
//
|
||||
// When this happens, we have two options. If the Linux kernel is new
|
||||
// enough (4.11+), we can read the arm64 registers directly which'll
|
||||
// trap into the kernel and then return back to userspace.
|
||||
//
|
||||
// But on older kernels, such as Linux 4.4.180 as used on many Synology
|
||||
// devices, calling readARM64Registers (specifically getisar0) will
|
||||
// cause a SIGILL and we'll die. So for older kernels, parse /proc/cpuinfo
|
||||
// instead.
|
||||
//
|
||||
// See golang/go#57336.
|
||||
if linuxKernelCanEmulateCPUID() {
|
||||
readARM64Registers()
|
||||
} else {
|
||||
readLinuxProcCPUInfo()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HWCAP feature bits
|
||||
ARM64.HasFP = isSet(hwCap, hwcap_FP)
|
||||
ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
|
||||
ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||
ARM64.HasAES = isSet(hwCap, hwcap_AES)
|
||||
ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
|
||||
ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
|
||||
ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
|
||||
ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
|
||||
ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
|
||||
ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
|
||||
ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
|
||||
ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
|
||||
ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
|
||||
ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
|
||||
ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
|
||||
ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
|
||||
ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
|
||||
ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
|
||||
ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
|
||||
ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
|
||||
ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
|
||||
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
||||
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
||||
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
||||
ARM64.HasDIT = isSet(hwCap, hwcap_DIT)
|
||||
|
||||
// HWCAP2 feature bits
|
||||
ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)
|
||||
ARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Copyright 2025 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 cpu
|
||||
|
||||
// HWCAP bits. These are exposed by the Linux kernel.
|
||||
const (
|
||||
hwcap_LOONGARCH_LSX = 1 << 4
|
||||
hwcap_LOONGARCH_LASX = 1 << 5
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// TODO: Features that require kernel support like LSX and LASX can
|
||||
// be detected here once needed in std library or by the compiler.
|
||||
Loong64.HasLSX = hwcIsSet(hwCap, hwcap_LOONGARCH_LSX)
|
||||
Loong64.HasLASX = hwcIsSet(hwCap, hwcap_LOONGARCH_LASX)
|
||||
}
|
||||
|
||||
func hwcIsSet(hwc uint, val uint) bool {
|
||||
return hwc&val != 0
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// Copyright 2020 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 linux && (mips64 || mips64le)
|
||||
|
||||
package cpu
|
||||
|
||||
// HWCAP bits. These are exposed by the Linux kernel 5.4.
|
||||
const (
|
||||
// CPU features
|
||||
hwcap_MIPS_MSA = 1 << 1
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// HWCAP feature bits
|
||||
MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// 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 linux && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64
|
||||
|
||||
package cpu
|
||||
|
||||
func doinit() {}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2018 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 linux && (ppc64 || ppc64le)
|
||||
|
||||
package cpu
|
||||
|
||||
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||
const (
|
||||
// ISA Level
|
||||
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
|
||||
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
|
||||
|
||||
// CPU features
|
||||
_PPC_FEATURE2_DARN = 0x00200000
|
||||
_PPC_FEATURE2_SCV = 0x00100000
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// HWCAP2 feature bits
|
||||
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
|
||||
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
|
||||
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
|
||||
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
// Copyright 2024 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 cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// RISC-V extension discovery code for Linux. The approach here is to first try the riscv_hwprobe
|
||||
// syscall falling back to HWCAP to check for the C extension if riscv_hwprobe is not available.
|
||||
//
|
||||
// A note on detection of the Vector extension using HWCAP.
|
||||
//
|
||||
// Support for the Vector extension version 1.0 was added to the Linux kernel in release 6.5.
|
||||
// Support for the riscv_hwprobe syscall was added in 6.4. It follows that if the riscv_hwprobe
|
||||
// syscall is not available then neither is the Vector extension (which needs kernel support).
|
||||
// The riscv_hwprobe syscall should then be all we need to detect the Vector extension.
|
||||
// However, some RISC-V board manufacturers ship boards with an older kernel on top of which
|
||||
// they have back-ported various versions of the Vector extension patches but not the riscv_hwprobe
|
||||
// patches. These kernels advertise support for the Vector extension using HWCAP. Falling
|
||||
// back to HWCAP to detect the Vector extension, if riscv_hwprobe is not available, or simply not
|
||||
// bothering with riscv_hwprobe at all and just using HWCAP may then seem like an attractive option.
|
||||
//
|
||||
// Unfortunately, simply checking the 'V' bit in AT_HWCAP will not work as this bit is used by
|
||||
// RISC-V board and cloud instance providers to mean different things. The Lichee Pi 4A board
|
||||
// and the Scaleway RV1 cloud instances use the 'V' bit to advertise their support for the unratified
|
||||
// 0.7.1 version of the Vector Specification. The Banana Pi BPI-F3 and the CanMV-K230 board use
|
||||
// it to advertise support for 1.0 of the Vector extension. Versions 0.7.1 and 1.0 of the Vector
|
||||
// extension are binary incompatible. HWCAP can then not be used in isolation to populate the
|
||||
// HasV field as this field indicates that the underlying CPU is compatible with RVV 1.0.
|
||||
//
|
||||
// There is a way at runtime to distinguish between versions 0.7.1 and 1.0 of the Vector
|
||||
// specification by issuing a RVV 1.0 vsetvli instruction and checking the vill bit of the vtype
|
||||
// register. This check would allow us to safely detect version 1.0 of the Vector extension
|
||||
// with HWCAP, if riscv_hwprobe were not available. However, the check cannot
|
||||
// be added until the assembler supports the Vector instructions.
|
||||
//
|
||||
// Note the riscv_hwprobe syscall does not suffer from these ambiguities by design as all of the
|
||||
// extensions it advertises support for are explicitly versioned. It's also worth noting that
|
||||
// the riscv_hwprobe syscall is the only way to detect multi-letter RISC-V extensions, e.g., Zba.
|
||||
// These cannot be detected using HWCAP and so riscv_hwprobe must be used to detect the majority
|
||||
// of RISC-V extensions.
|
||||
//
|
||||
// Please see https://docs.kernel.org/arch/riscv/hwprobe.html for more information.
|
||||
|
||||
// golang.org/x/sys/cpu is not allowed to depend on golang.org/x/sys/unix so we must
|
||||
// reproduce the constants, types and functions needed to make the riscv_hwprobe syscall
|
||||
// here.
|
||||
|
||||
const (
|
||||
// Copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go.
|
||||
riscv_HWPROBE_KEY_IMA_EXT_0 = 0x4
|
||||
riscv_HWPROBE_IMA_C = 0x2
|
||||
riscv_HWPROBE_IMA_V = 0x4
|
||||
riscv_HWPROBE_EXT_ZBA = 0x8
|
||||
riscv_HWPROBE_EXT_ZBB = 0x10
|
||||
riscv_HWPROBE_EXT_ZBS = 0x20
|
||||
riscv_HWPROBE_EXT_ZVBB = 0x20000
|
||||
riscv_HWPROBE_EXT_ZVBC = 0x40000
|
||||
riscv_HWPROBE_EXT_ZVKB = 0x80000
|
||||
riscv_HWPROBE_EXT_ZVKG = 0x100000
|
||||
riscv_HWPROBE_EXT_ZVKNED = 0x200000
|
||||
riscv_HWPROBE_EXT_ZVKNHB = 0x800000
|
||||
riscv_HWPROBE_EXT_ZVKSED = 0x1000000
|
||||
riscv_HWPROBE_EXT_ZVKSH = 0x2000000
|
||||
riscv_HWPROBE_EXT_ZVKT = 0x4000000
|
||||
riscv_HWPROBE_KEY_CPUPERF_0 = 0x5
|
||||
riscv_HWPROBE_MISALIGNED_FAST = 0x3
|
||||
riscv_HWPROBE_MISALIGNED_MASK = 0x7
|
||||
)
|
||||
|
||||
const (
|
||||
// sys_RISCV_HWPROBE is copied from golang.org/x/sys/unix/zsysnum_linux_riscv64.go.
|
||||
sys_RISCV_HWPROBE = 258
|
||||
)
|
||||
|
||||
// riscvHWProbePairs is copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go.
|
||||
type riscvHWProbePairs struct {
|
||||
key int64
|
||||
value uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// CPU features
|
||||
hwcap_RISCV_ISA_C = 1 << ('C' - 'A')
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// A slice of key/value pair structures is passed to the RISCVHWProbe syscall. The key
|
||||
// field should be initialised with one of the key constants defined above, e.g.,
|
||||
// RISCV_HWPROBE_KEY_IMA_EXT_0. The syscall will set the value field to the appropriate value.
|
||||
// If the kernel does not recognise a key it will set the key field to -1 and the value field to 0.
|
||||
|
||||
pairs := []riscvHWProbePairs{
|
||||
{riscv_HWPROBE_KEY_IMA_EXT_0, 0},
|
||||
{riscv_HWPROBE_KEY_CPUPERF_0, 0},
|
||||
}
|
||||
|
||||
// This call only indicates that extensions are supported if they are implemented on all cores.
|
||||
if riscvHWProbe(pairs, 0) {
|
||||
if pairs[0].key != -1 {
|
||||
v := uint(pairs[0].value)
|
||||
RISCV64.HasC = isSet(v, riscv_HWPROBE_IMA_C)
|
||||
RISCV64.HasV = isSet(v, riscv_HWPROBE_IMA_V)
|
||||
RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA)
|
||||
RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB)
|
||||
RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS)
|
||||
RISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB)
|
||||
RISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC)
|
||||
RISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB)
|
||||
RISCV64.HasZvkg = isSet(v, riscv_HWPROBE_EXT_ZVKG)
|
||||
RISCV64.HasZvkt = isSet(v, riscv_HWPROBE_EXT_ZVKT)
|
||||
// Cryptography shorthand extensions
|
||||
RISCV64.HasZvkn = isSet(v, riscv_HWPROBE_EXT_ZVKNED) &&
|
||||
isSet(v, riscv_HWPROBE_EXT_ZVKNHB) && RISCV64.HasZvkb && RISCV64.HasZvkt
|
||||
RISCV64.HasZvknc = RISCV64.HasZvkn && RISCV64.HasZvbc
|
||||
RISCV64.HasZvkng = RISCV64.HasZvkn && RISCV64.HasZvkg
|
||||
RISCV64.HasZvks = isSet(v, riscv_HWPROBE_EXT_ZVKSED) &&
|
||||
isSet(v, riscv_HWPROBE_EXT_ZVKSH) && RISCV64.HasZvkb && RISCV64.HasZvkt
|
||||
RISCV64.HasZvksc = RISCV64.HasZvks && RISCV64.HasZvbc
|
||||
RISCV64.HasZvksg = RISCV64.HasZvks && RISCV64.HasZvkg
|
||||
}
|
||||
if pairs[1].key != -1 {
|
||||
v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK
|
||||
RISCV64.HasFastMisaligned = v == riscv_HWPROBE_MISALIGNED_FAST
|
||||
}
|
||||
}
|
||||
|
||||
// Let's double check with HWCAP if the C extension does not appear to be supported.
|
||||
// This may happen if we're running on a kernel older than 6.4.
|
||||
|
||||
if !RISCV64.HasC {
|
||||
RISCV64.HasC = isSet(hwCap, hwcap_RISCV_ISA_C)
|
||||
}
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
|
||||
// riscvHWProbe is a simplified version of the generated wrapper function found in
|
||||
// golang.org/x/sys/unix/zsyscall_linux_riscv64.go. We simplify it by removing the
|
||||
// cpuCount and cpus parameters which we do not need. We always want to pass 0 for
|
||||
// these parameters here so the kernel only reports the extensions that are present
|
||||
// on all cores.
|
||||
func riscvHWProbe(pairs []riscvHWProbePairs, flags uint) bool {
|
||||
var _zero uintptr
|
||||
var p0 unsafe.Pointer
|
||||
if len(pairs) > 0 {
|
||||
p0 = unsafe.Pointer(&pairs[0])
|
||||
} else {
|
||||
p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
|
||||
_, _, e1 := syscall.Syscall6(sys_RISCV_HWPROBE, uintptr(p0), uintptr(len(pairs)), uintptr(0), uintptr(0), uintptr(flags), 0)
|
||||
return e1 == 0
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
|
||||
package cpu
|
||||
|
||||
const (
|
||||
// bit mask values from /usr/include/bits/hwcap.h
|
||||
hwcap_ZARCH = 2
|
||||
hwcap_STFLE = 4
|
||||
hwcap_MSA = 8
|
||||
hwcap_LDISP = 16
|
||||
hwcap_EIMM = 32
|
||||
hwcap_DFP = 64
|
||||
hwcap_ETF3EH = 256
|
||||
hwcap_VX = 2048
|
||||
hwcap_VXE = 8192
|
||||
)
|
||||
|
||||
func initS390Xbase() {
|
||||
// test HWCAP bit vector
|
||||
has := func(featureMask uint) bool {
|
||||
return hwCap&featureMask == featureMask
|
||||
}
|
||||
|
||||
// mandatory
|
||||
S390X.HasZARCH = has(hwcap_ZARCH)
|
||||
|
||||
// optional
|
||||
S390X.HasSTFLE = has(hwcap_STFLE)
|
||||
S390X.HasLDISP = has(hwcap_LDISP)
|
||||
S390X.HasEIMM = has(hwcap_EIMM)
|
||||
S390X.HasETF3EH = has(hwcap_ETF3EH)
|
||||
S390X.HasDFP = has(hwcap_DFP)
|
||||
S390X.HasMSA = has(hwcap_MSA)
|
||||
S390X.HasVX = has(hwcap_VX)
|
||||
if S390X.HasVX {
|
||||
S390X.HasVXE = has(hwcap_VXE)
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// Copyright 2022 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 loong64
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
// Bit fields for CPUCFG registers, Related reference documents:
|
||||
// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_cpucfg
|
||||
const (
|
||||
// CPUCFG1 bits
|
||||
cpucfg1_CRC32 = 1 << 25
|
||||
|
||||
// CPUCFG2 bits
|
||||
cpucfg2_LAM_BH = 1 << 27
|
||||
cpucfg2_LAMCAS = 1 << 28
|
||||
)
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "lsx", Feature: &Loong64.HasLSX},
|
||||
{Name: "lasx", Feature: &Loong64.HasLASX},
|
||||
{Name: "crc32", Feature: &Loong64.HasCRC32},
|
||||
{Name: "lam_bh", Feature: &Loong64.HasLAM_BH},
|
||||
{Name: "lamcas", Feature: &Loong64.HasLAMCAS},
|
||||
}
|
||||
|
||||
// The CPUCFG data on Loong64 only reflects the hardware capabilities,
|
||||
// not the kernel support status, so features such as LSX and LASX that
|
||||
// require kernel support cannot be obtained from the CPUCFG data.
|
||||
//
|
||||
// These features only require hardware capability support and do not
|
||||
// require kernel specific support, so they can be obtained directly
|
||||
// through CPUCFG
|
||||
cfg1 := get_cpucfg(1)
|
||||
cfg2 := get_cpucfg(2)
|
||||
|
||||
Loong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32)
|
||||
Loong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS)
|
||||
Loong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH)
|
||||
}
|
||||
|
||||
func get_cpucfg(reg uint32) uint32
|
||||
|
||||
func cfgIsSet(cfg uint32, val uint32) bool {
|
||||
return cfg&val != 0
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Copyright 2025 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"
|
||||
|
||||
// func get_cpucfg(reg uint32) uint32
|
||||
TEXT ·get_cpucfg(SB), NOSPLIT|NOFRAME, $0
|
||||
MOVW reg+0(FP), R5
|
||||
// CPUCFG R5, R4 = 0x00006ca4
|
||||
WORD $0x00006ca4
|
||||
MOVW R4, ret+8(FP)
|
||||
RET
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// Copyright 2018 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 mips64 || mips64le
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "msa", Feature: &MIPS64X.HasMSA},
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2018 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 mips || mipsle
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func initOptions() {}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
// Copyright 2020 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 cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Minimal copy of functionality from x/sys/unix so the cpu package can call
|
||||
// sysctl without depending on x/sys/unix.
|
||||
|
||||
const (
|
||||
_CTL_QUERY = -2
|
||||
|
||||
_SYSCTL_VERS_1 = 0x1000000
|
||||
)
|
||||
|
||||
var _zero uintptr
|
||||
|
||||
func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(mib) > 0 {
|
||||
_p0 = unsafe.Pointer(&mib[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
_, _, errno := syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(_p0),
|
||||
uintptr(len(mib)),
|
||||
uintptr(unsafe.Pointer(old)),
|
||||
uintptr(unsafe.Pointer(oldlen)),
|
||||
uintptr(unsafe.Pointer(new)),
|
||||
uintptr(newlen))
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type sysctlNode struct {
|
||||
Flags uint32
|
||||
Num int32
|
||||
Name [32]int8
|
||||
Ver uint32
|
||||
__rsvd uint32
|
||||
Un [16]byte
|
||||
_sysctl_size [8]byte
|
||||
_sysctl_func [8]byte
|
||||
_sysctl_parent [8]byte
|
||||
_sysctl_desc [8]byte
|
||||
}
|
||||
|
||||
func sysctlNodes(mib []int32) ([]sysctlNode, error) {
|
||||
var olen uintptr
|
||||
|
||||
// Get a list of all sysctl nodes below the given MIB by performing
|
||||
// a sysctl for the given MIB with CTL_QUERY appended.
|
||||
mib = append(mib, _CTL_QUERY)
|
||||
qnode := sysctlNode{Flags: _SYSCTL_VERS_1}
|
||||
qp := (*byte)(unsafe.Pointer(&qnode))
|
||||
sz := unsafe.Sizeof(qnode)
|
||||
if err := sysctl(mib, nil, &olen, qp, sz); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now that we know the size, get the actual nodes.
|
||||
nodes := make([]sysctlNode, olen/sz)
|
||||
np := (*byte)(unsafe.Pointer(&nodes[0]))
|
||||
if err := sysctl(mib, np, &olen, qp, sz); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func nametomib(name string) ([]int32, error) {
|
||||
// Split name into components.
|
||||
var parts []string
|
||||
last := 0
|
||||
for i := 0; i < len(name); i++ {
|
||||
if name[i] == '.' {
|
||||
parts = append(parts, name[last:i])
|
||||
last = i + 1
|
||||
}
|
||||
}
|
||||
parts = append(parts, name[last:])
|
||||
|
||||
mib := []int32{}
|
||||
// Discover the nodes and construct the MIB OID.
|
||||
for partno, part := range parts {
|
||||
nodes, err := sysctlNodes(mib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, node := range nodes {
|
||||
n := make([]byte, 0)
|
||||
for i := range node.Name {
|
||||
if node.Name[i] != 0 {
|
||||
n = append(n, byte(node.Name[i]))
|
||||
}
|
||||
}
|
||||
if string(n) == part {
|
||||
mib = append(mib, int32(node.Num))
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(mib) != partno+1 {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return mib, nil
|
||||
}
|
||||
|
||||
// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's <aarch64/armreg.h>
|
||||
type aarch64SysctlCPUID struct {
|
||||
midr uint64 /* Main ID Register */
|
||||
revidr uint64 /* Revision ID Register */
|
||||
mpidr uint64 /* Multiprocessor Affinity Register */
|
||||
aa64dfr0 uint64 /* A64 Debug Feature Register 0 */
|
||||
aa64dfr1 uint64 /* A64 Debug Feature Register 1 */
|
||||
aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */
|
||||
aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */
|
||||
aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */
|
||||
aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */
|
||||
aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */
|
||||
aa64pfr0 uint64 /* A64 Processor Feature Register 0 */
|
||||
aa64pfr1 uint64 /* A64 Processor Feature Register 1 */
|
||||
aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */
|
||||
mvfr0 uint32 /* Media and VFP Feature Register 0 */
|
||||
mvfr1 uint32 /* Media and VFP Feature Register 1 */
|
||||
mvfr2 uint32 /* Media and VFP Feature Register 2 */
|
||||
pad uint32
|
||||
clidr uint64 /* Cache Level ID Register */
|
||||
ctr uint64 /* Cache Type Register */
|
||||
}
|
||||
|
||||
func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) {
|
||||
mib, err := nametomib(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := aarch64SysctlCPUID{}
|
||||
n := unsafe.Sizeof(out)
|
||||
_, _, errno := syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(unsafe.Pointer(&mib[0])),
|
||||
uintptr(len(mib)),
|
||||
uintptr(unsafe.Pointer(&out)),
|
||||
uintptr(unsafe.Pointer(&n)),
|
||||
uintptr(0),
|
||||
uintptr(0))
|
||||
if errno != 0 {
|
||||
return nil, errno
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func doinit() {
|
||||
cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id")
|
||||
if err != nil {
|
||||
setMinimalFeatures()
|
||||
return
|
||||
}
|
||||
parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0)
|
||||
|
||||
Initialized = true
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2022 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 cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Minimal copy of functionality from x/sys/unix so the cpu package can call
|
||||
// sysctl without depending on x/sys/unix.
|
||||
|
||||
const (
|
||||
// From OpenBSD's sys/sysctl.h.
|
||||
_CTL_MACHDEP = 7
|
||||
|
||||
// From OpenBSD's machine/cpu.h.
|
||||
_CPU_ID_AA64ISAR0 = 2
|
||||
_CPU_ID_AA64ISAR1 = 3
|
||||
)
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
|
||||
func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||
_, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var libc_sysctl_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
|
||||
|
||||
func sysctlUint64(mib []uint32) (uint64, bool) {
|
||||
var out uint64
|
||||
nout := unsafe.Sizeof(out)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
func doinit() {
|
||||
setMinimalFeatures()
|
||||
|
||||
// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
|
||||
isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
parseARM64SystemRegisters(isar0, isar1, 0)
|
||||
|
||||
Initialized = true
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2022 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 libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
|
||||
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Copyright 2020 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 !linux && arm
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// 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 !linux && !netbsd && !openbsd && !windows && arm64
|
||||
|
||||
package cpu
|
||||
|
||||
func doinit() {}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2020 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 !linux && (mips64 || mips64le)
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {
|
||||
Initialized = true
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// Copyright 2022 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 !aix && !linux && (ppc64 || ppc64le)
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {
|
||||
PPC64.IsPOWER8 = true
|
||||
Initialized = true
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2022 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 !linux && riscv64
|
||||
|
||||
package cpu
|
||||
|
||||
func archInit() {
|
||||
Initialized = true
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// Copyright 2024 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 386 || amd64p32 || (amd64 && (!darwin || !gc))
|
||||
|
||||
package cpu
|
||||
|
||||
func darwinSupportsAVX512() bool {
|
||||
panic("only implemented for gc && amd64 && darwin")
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// Copyright 2020 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 ppc64 || ppc64le
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 128
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "darn", Feature: &PPC64.HasDARN},
|
||||
{Name: "scv", Feature: &PPC64.HasSCV},
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// 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 riscv64
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "fastmisaligned", Feature: &RISCV64.HasFastMisaligned},
|
||||
{Name: "c", Feature: &RISCV64.HasC},
|
||||
{Name: "v", Feature: &RISCV64.HasV},
|
||||
{Name: "zba", Feature: &RISCV64.HasZba},
|
||||
{Name: "zbb", Feature: &RISCV64.HasZbb},
|
||||
{Name: "zbs", Feature: &RISCV64.HasZbs},
|
||||
// RISC-V Cryptography Extensions
|
||||
{Name: "zvbb", Feature: &RISCV64.HasZvbb},
|
||||
{Name: "zvbc", Feature: &RISCV64.HasZvbc},
|
||||
{Name: "zvkb", Feature: &RISCV64.HasZvkb},
|
||||
{Name: "zvkg", Feature: &RISCV64.HasZvkg},
|
||||
{Name: "zvkt", Feature: &RISCV64.HasZvkt},
|
||||
{Name: "zvkn", Feature: &RISCV64.HasZvkn},
|
||||
{Name: "zvknc", Feature: &RISCV64.HasZvknc},
|
||||
{Name: "zvkng", Feature: &RISCV64.HasZvkng},
|
||||
{Name: "zvks", Feature: &RISCV64.HasZvks},
|
||||
{Name: "zvksc", Feature: &RISCV64.HasZvksc},
|
||||
{Name: "zvksg", Feature: &RISCV64.HasZvksg},
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
// Copyright 2020 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 cpu
|
||||
|
||||
const cacheLineSize = 256
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "zarch", Feature: &S390X.HasZARCH, Required: true},
|
||||
{Name: "stfle", Feature: &S390X.HasSTFLE, Required: true},
|
||||
{Name: "ldisp", Feature: &S390X.HasLDISP, Required: true},
|
||||
{Name: "eimm", Feature: &S390X.HasEIMM, Required: true},
|
||||
{Name: "dfp", Feature: &S390X.HasDFP},
|
||||
{Name: "etf3eh", Feature: &S390X.HasETF3EH},
|
||||
{Name: "msa", Feature: &S390X.HasMSA},
|
||||
{Name: "aes", Feature: &S390X.HasAES},
|
||||
{Name: "aescbc", Feature: &S390X.HasAESCBC},
|
||||
{Name: "aesctr", Feature: &S390X.HasAESCTR},
|
||||
{Name: "aesgcm", Feature: &S390X.HasAESGCM},
|
||||
{Name: "ghash", Feature: &S390X.HasGHASH},
|
||||
{Name: "sha1", Feature: &S390X.HasSHA1},
|
||||
{Name: "sha256", Feature: &S390X.HasSHA256},
|
||||
{Name: "sha3", Feature: &S390X.HasSHA3},
|
||||
{Name: "sha512", Feature: &S390X.HasSHA512},
|
||||
{Name: "vx", Feature: &S390X.HasVX},
|
||||
{Name: "vxe", Feature: &S390X.HasVXE},
|
||||
}
|
||||
}
|
||||
|
||||
// bitIsSet reports whether the bit at index is set. The bit index
|
||||
// is in big endian order, so bit index 0 is the leftmost bit.
|
||||
func bitIsSet(bits []uint64, index uint) bool {
|
||||
return bits[index/64]&((1<<63)>>(index%64)) != 0
|
||||
}
|
||||
|
||||
// facility is a bit index for the named facility.
|
||||
type facility uint8
|
||||
|
||||
const (
|
||||
// mandatory facilities
|
||||
zarch facility = 1 // z architecture mode is active
|
||||
stflef facility = 7 // store-facility-list-extended
|
||||
ldisp facility = 18 // long-displacement
|
||||
eimm facility = 21 // extended-immediate
|
||||
|
||||
// miscellaneous facilities
|
||||
dfp facility = 42 // decimal-floating-point
|
||||
etf3eh facility = 30 // extended-translation 3 enhancement
|
||||
|
||||
// cryptography facilities
|
||||
msa facility = 17 // message-security-assist
|
||||
msa3 facility = 76 // message-security-assist extension 3
|
||||
msa4 facility = 77 // message-security-assist extension 4
|
||||
msa5 facility = 57 // message-security-assist extension 5
|
||||
msa8 facility = 146 // message-security-assist extension 8
|
||||
msa9 facility = 155 // message-security-assist extension 9
|
||||
|
||||
// vector facilities
|
||||
vx facility = 129 // vector facility
|
||||
vxe facility = 135 // vector-enhancements 1
|
||||
vxe2 facility = 148 // vector-enhancements 2
|
||||
)
|
||||
|
||||
// facilityList contains the result of an STFLE call.
|
||||
// Bits are numbered in big endian order so the
|
||||
// leftmost bit (the MSB) is at index 0.
|
||||
type facilityList struct {
|
||||
bits [4]uint64
|
||||
}
|
||||
|
||||
// Has reports whether the given facilities are present.
|
||||
func (s *facilityList) Has(fs ...facility) bool {
|
||||
if len(fs) == 0 {
|
||||
panic("no facility bits provided")
|
||||
}
|
||||
for _, f := range fs {
|
||||
if !bitIsSet(s.bits[:], uint(f)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// function is the code for the named cryptographic function.
|
||||
type function uint8
|
||||
|
||||
const (
|
||||
// KM{,A,C,CTR} function codes
|
||||
aes128 function = 18 // AES-128
|
||||
aes192 function = 19 // AES-192
|
||||
aes256 function = 20 // AES-256
|
||||
|
||||
// K{I,L}MD function codes
|
||||
sha1 function = 1 // SHA-1
|
||||
sha256 function = 2 // SHA-256
|
||||
sha512 function = 3 // SHA-512
|
||||
sha3_224 function = 32 // SHA3-224
|
||||
sha3_256 function = 33 // SHA3-256
|
||||
sha3_384 function = 34 // SHA3-384
|
||||
sha3_512 function = 35 // SHA3-512
|
||||
shake128 function = 36 // SHAKE-128
|
||||
shake256 function = 37 // SHAKE-256
|
||||
|
||||
// KLMD function codes
|
||||
ghash function = 65 // GHASH
|
||||
)
|
||||
|
||||
// queryResult contains the result of a Query function
|
||||
// call. Bits are numbered in big endian order so the
|
||||
// leftmost bit (the MSB) is at index 0.
|
||||
type queryResult struct {
|
||||
bits [2]uint64
|
||||
}
|
||||
|
||||
// Has reports whether the given functions are present.
|
||||
func (q *queryResult) Has(fns ...function) bool {
|
||||
if len(fns) == 0 {
|
||||
panic("no function codes provided")
|
||||
}
|
||||
for _, f := range fns {
|
||||
if !bitIsSet(q.bits[:], uint(f)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func doinit() {
|
||||
initS390Xbase()
|
||||
|
||||
// We need implementations of stfle, km and so on
|
||||
// to detect cryptographic features.
|
||||
if !haveAsmFunctions() {
|
||||
return
|
||||
}
|
||||
|
||||
// optional cryptographic functions
|
||||
if S390X.HasMSA {
|
||||
aes := []function{aes128, aes192, aes256}
|
||||
|
||||
// cipher message
|
||||
km, kmc := kmQuery(), kmcQuery()
|
||||
S390X.HasAES = km.Has(aes...)
|
||||
S390X.HasAESCBC = kmc.Has(aes...)
|
||||
if S390X.HasSTFLE {
|
||||
facilities := stfle()
|
||||
if facilities.Has(msa4) {
|
||||
kmctr := kmctrQuery()
|
||||
S390X.HasAESCTR = kmctr.Has(aes...)
|
||||
}
|
||||
if facilities.Has(msa8) {
|
||||
kma := kmaQuery()
|
||||
S390X.HasAESGCM = kma.Has(aes...)
|
||||
}
|
||||
}
|
||||
|
||||
// compute message digest
|
||||
kimd := kimdQuery() // intermediate (no padding)
|
||||
klmd := klmdQuery() // last (padding)
|
||||
S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
|
||||
S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
|
||||
S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
|
||||
S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
|
||||
sha3 := []function{
|
||||
sha3_224, sha3_256, sha3_384, sha3_512,
|
||||
shake128, shake256,
|
||||
}
|
||||
S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 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 gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func stfle() facilityList
|
||||
TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32
|
||||
MOVD $ret+0(FP), R1
|
||||
MOVD $3, R0 // last doubleword index to store
|
||||
XC $32, (R1), (R1) // clear 4 doublewords (32 bytes)
|
||||
WORD $0xb2b01000 // store facility list extended (STFLE)
|
||||
RET
|
||||
|
||||
// func kmQuery() queryResult
|
||||
TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KM-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xB92E0024 // cipher message (KM)
|
||||
RET
|
||||
|
||||
// func kmcQuery() queryResult
|
||||
TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KMC-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xB92F0024 // cipher message with chaining (KMC)
|
||||
RET
|
||||
|
||||
// func kmctrQuery() queryResult
|
||||
TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KMCTR-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xB92D4024 // cipher message with counter (KMCTR)
|
||||
RET
|
||||
|
||||
// func kmaQuery() queryResult
|
||||
TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KMA-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xb9296024 // cipher message with authentication (KMA)
|
||||
RET
|
||||
|
||||
// func kimdQuery() queryResult
|
||||
TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KIMD-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xB93E0024 // compute intermediate message digest (KIMD)
|
||||
RET
|
||||
|
||||
// func klmdQuery() queryResult
|
||||
TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD $0, R0 // set function code to 0 (KLMD-Query)
|
||||
MOVD $ret+0(FP), R1 // address of 16-byte return value
|
||||
WORD $0xB93F0024 // compute last message digest (KLMD)
|
||||
RET
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// 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 wasm
|
||||
|
||||
package cpu
|
||||
|
||||
// We're compiling the cpu package for an unknown (software-abstracted) CPU.
|
||||
// Make CacheLinePad an empty struct and hope that the usual struct alignment
|
||||
// rules are good enough.
|
||||
|
||||
const cacheLineSize = 0
|
||||
|
||||
func initOptions() {}
|
||||
|
||||
func archInit() {}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// Copyright 2026 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 cpu
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// set HasASIMD and HasFP to true as per
|
||||
// https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#base-requirements
|
||||
//
|
||||
// The ARM64 version of Windows always presupposes that it's running on an ARMv8 or later architecture.
|
||||
// Both floating-point and NEON support are presumed to be present in hardware.
|
||||
//
|
||||
ARM64.HasASIMD = true
|
||||
ARM64.HasFP = true
|
||||
|
||||
if windows.IsProcessorFeaturePresent(windows.PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) {
|
||||
ARM64.HasAES = true
|
||||
ARM64.HasPMULL = true
|
||||
ARM64.HasSHA1 = true
|
||||
ARM64.HasSHA2 = true
|
||||
}
|
||||
ARM64.HasSHA3 = windows.IsProcessorFeaturePresent(windows.PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE)
|
||||
ARM64.HasCRC32 = windows.IsProcessorFeaturePresent(windows.PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)
|
||||
ARM64.HasSHA512 = windows.IsProcessorFeaturePresent(windows.PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE)
|
||||
ARM64.HasATOMICS = windows.IsProcessorFeaturePresent(windows.PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE)
|
||||
if windows.IsProcessorFeaturePresent(windows.PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) {
|
||||
ARM64.HasASIMDDP = true
|
||||
ARM64.HasASIMDRDM = true
|
||||
}
|
||||
if windows.IsProcessorFeaturePresent(windows.PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE) {
|
||||
ARM64.HasLRCPC = true
|
||||
ARM64.HasSM3 = true
|
||||
}
|
||||
ARM64.HasSVE = windows.IsProcessorFeaturePresent(windows.PF_ARM_SVE_INSTRUCTIONS_AVAILABLE)
|
||||
ARM64.HasSVE2 = windows.IsProcessorFeaturePresent(windows.PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE)
|
||||
ARM64.HasJSCVT = windows.IsProcessorFeaturePresent(windows.PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE)
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
// Copyright 2018 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 386 || amd64 || amd64p32
|
||||
|
||||
package cpu
|
||||
|
||||
import "runtime"
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
func initOptions() {
|
||||
options = []option{
|
||||
{Name: "adx", Feature: &X86.HasADX},
|
||||
{Name: "aes", Feature: &X86.HasAES},
|
||||
{Name: "avx", Feature: &X86.HasAVX},
|
||||
{Name: "avx2", Feature: &X86.HasAVX2},
|
||||
{Name: "avx512", Feature: &X86.HasAVX512},
|
||||
{Name: "avx512f", Feature: &X86.HasAVX512F},
|
||||
{Name: "avx512cd", Feature: &X86.HasAVX512CD},
|
||||
{Name: "avx512er", Feature: &X86.HasAVX512ER},
|
||||
{Name: "avx512pf", Feature: &X86.HasAVX512PF},
|
||||
{Name: "avx512vl", Feature: &X86.HasAVX512VL},
|
||||
{Name: "avx512bw", Feature: &X86.HasAVX512BW},
|
||||
{Name: "avx512dq", Feature: &X86.HasAVX512DQ},
|
||||
{Name: "avx512ifma", Feature: &X86.HasAVX512IFMA},
|
||||
{Name: "avx512vbmi", Feature: &X86.HasAVX512VBMI},
|
||||
{Name: "avx512vnniw", Feature: &X86.HasAVX5124VNNIW},
|
||||
{Name: "avx5124fmaps", Feature: &X86.HasAVX5124FMAPS},
|
||||
{Name: "avx512vpopcntdq", Feature: &X86.HasAVX512VPOPCNTDQ},
|
||||
{Name: "avx512vpclmulqdq", Feature: &X86.HasAVX512VPCLMULQDQ},
|
||||
{Name: "avx512vnni", Feature: &X86.HasAVX512VNNI},
|
||||
{Name: "avx512gfni", Feature: &X86.HasAVX512GFNI},
|
||||
{Name: "avx512vaes", Feature: &X86.HasAVX512VAES},
|
||||
{Name: "avx512vbmi2", Feature: &X86.HasAVX512VBMI2},
|
||||
{Name: "avx512bitalg", Feature: &X86.HasAVX512BITALG},
|
||||
{Name: "avx512bf16", Feature: &X86.HasAVX512BF16},
|
||||
{Name: "amxtile", Feature: &X86.HasAMXTile},
|
||||
{Name: "amxint8", Feature: &X86.HasAMXInt8},
|
||||
{Name: "amxbf16", Feature: &X86.HasAMXBF16},
|
||||
{Name: "bmi1", Feature: &X86.HasBMI1},
|
||||
{Name: "bmi2", Feature: &X86.HasBMI2},
|
||||
{Name: "cx16", Feature: &X86.HasCX16},
|
||||
{Name: "erms", Feature: &X86.HasERMS},
|
||||
{Name: "fma", Feature: &X86.HasFMA},
|
||||
{Name: "osxsave", Feature: &X86.HasOSXSAVE},
|
||||
{Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ},
|
||||
{Name: "popcnt", Feature: &X86.HasPOPCNT},
|
||||
{Name: "rdrand", Feature: &X86.HasRDRAND},
|
||||
{Name: "rdseed", Feature: &X86.HasRDSEED},
|
||||
{Name: "sse3", Feature: &X86.HasSSE3},
|
||||
{Name: "sse41", Feature: &X86.HasSSE41},
|
||||
{Name: "sse42", Feature: &X86.HasSSE42},
|
||||
{Name: "ssse3", Feature: &X86.HasSSSE3},
|
||||
{Name: "avxifma", Feature: &X86.HasAVXIFMA},
|
||||
{Name: "avxvnni", Feature: &X86.HasAVXVNNI},
|
||||
{Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8},
|
||||
|
||||
// These capabilities should always be enabled on amd64:
|
||||
{Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
|
||||
}
|
||||
}
|
||||
|
||||
func archInit() {
|
||||
|
||||
// From internal/cpu
|
||||
const (
|
||||
// eax bits
|
||||
cpuid_AVXVNNI = 1 << 4
|
||||
|
||||
// ecx bits
|
||||
cpuid_SSE3 = 1 << 0
|
||||
cpuid_PCLMULQDQ = 1 << 1
|
||||
cpuid_AVX512VBMI = 1 << 1
|
||||
cpuid_AVX512VBMI2 = 1 << 6
|
||||
cpuid_SSSE3 = 1 << 9
|
||||
cpuid_AVX512GFNI = 1 << 8
|
||||
cpuid_AVX512VAES = 1 << 9
|
||||
cpuid_AVX512VNNI = 1 << 11
|
||||
cpuid_AVX512BITALG = 1 << 12
|
||||
cpuid_FMA = 1 << 12
|
||||
cpuid_AVX512VPOPCNTDQ = 1 << 14
|
||||
cpuid_SSE41 = 1 << 19
|
||||
cpuid_SSE42 = 1 << 20
|
||||
cpuid_POPCNT = 1 << 23
|
||||
cpuid_AES = 1 << 25
|
||||
cpuid_OSXSAVE = 1 << 27
|
||||
cpuid_AVX = 1 << 28
|
||||
|
||||
// "Extended Feature Flag" bits returned in EBX for CPUID EAX=0x7 ECX=0x0
|
||||
cpuid_BMI1 = 1 << 3
|
||||
cpuid_AVX2 = 1 << 5
|
||||
cpuid_BMI2 = 1 << 8
|
||||
cpuid_ERMS = 1 << 9
|
||||
cpuid_AVX512F = 1 << 16
|
||||
cpuid_AVX512DQ = 1 << 17
|
||||
cpuid_ADX = 1 << 19
|
||||
cpuid_AVX512CD = 1 << 28
|
||||
cpuid_SHA = 1 << 29
|
||||
cpuid_AVX512BW = 1 << 30
|
||||
cpuid_AVX512VL = 1 << 31
|
||||
|
||||
// "Extended Feature Flag" bits returned in ECX for CPUID EAX=0x7 ECX=0x0
|
||||
cpuid_AVX512_VBMI = 1 << 1
|
||||
cpuid_AVX512_VBMI2 = 1 << 6
|
||||
cpuid_GFNI = 1 << 8
|
||||
cpuid_AVX512VPCLMULQDQ = 1 << 10
|
||||
cpuid_AVX512_BITALG = 1 << 12
|
||||
|
||||
// edx bits
|
||||
cpuid_FSRM = 1 << 4
|
||||
// edx bits for CPUID 0x80000001
|
||||
cpuid_RDTSCP = 1 << 27
|
||||
)
|
||||
// Additional constants not in internal/cpu
|
||||
const (
|
||||
// eax=1: edx
|
||||
cpuid_SSE2 = 1 << 26
|
||||
// eax=1: ecx
|
||||
cpuid_CX16 = 1 << 13
|
||||
cpuid_RDRAND = 1 << 30
|
||||
// eax=7,ecx=0: ebx
|
||||
cpuid_RDSEED = 1 << 18
|
||||
cpuid_AVX512IFMA = 1 << 21
|
||||
cpuid_AVX512PF = 1 << 26
|
||||
cpuid_AVX512ER = 1 << 27
|
||||
// eax=7,ecx=0: edx
|
||||
cpuid_AVX5124VNNIW = 1 << 2
|
||||
cpuid_AVX5124FMAPS = 1 << 3
|
||||
cpuid_AMXBF16 = 1 << 22
|
||||
cpuid_AMXTile = 1 << 24
|
||||
cpuid_AMXInt8 = 1 << 25
|
||||
// eax=7,ecx=1: eax
|
||||
cpuid_AVX512BF16 = 1 << 5
|
||||
cpuid_AVXIFMA = 1 << 23
|
||||
// eax=7,ecx=1: edx
|
||||
cpuid_AVXVNNIInt8 = 1 << 4
|
||||
)
|
||||
|
||||
Initialized = true
|
||||
|
||||
maxID, _, _, _ := cpuid(0, 0)
|
||||
|
||||
if maxID < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, ecx1, edx1 := cpuid(1, 0)
|
||||
X86.HasSSE2 = isSet(edx1, cpuid_SSE2)
|
||||
|
||||
X86.HasSSE3 = isSet(ecx1, cpuid_SSE3)
|
||||
X86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ)
|
||||
X86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3)
|
||||
X86.HasFMA = isSet(ecx1, cpuid_FMA)
|
||||
X86.HasCX16 = isSet(ecx1, cpuid_CX16)
|
||||
X86.HasSSE41 = isSet(ecx1, cpuid_SSE41)
|
||||
X86.HasSSE42 = isSet(ecx1, cpuid_SSE42)
|
||||
X86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT)
|
||||
X86.HasAES = isSet(ecx1, cpuid_AES)
|
||||
X86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE)
|
||||
X86.HasRDRAND = isSet(ecx1, cpuid_RDRAND)
|
||||
|
||||
var osSupportsAVX, osSupportsAVX512 bool
|
||||
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||
if X86.HasOSXSAVE {
|
||||
eax, _ := xgetbv()
|
||||
// Check if XMM and YMM registers have OS support.
|
||||
osSupportsAVX = isSet(eax, 1<<1) && isSet(eax, 1<<2)
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
// Darwin requires special AVX512 checks, see cpu_darwin_x86.go
|
||||
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
|
||||
} else {
|
||||
// Check if OPMASK and ZMM registers have OS support.
|
||||
osSupportsAVX512 = osSupportsAVX && isSet(eax, 1<<5) && isSet(eax, 1<<6) && isSet(eax, 1<<7)
|
||||
}
|
||||
}
|
||||
|
||||
X86.HasAVX = isSet(ecx1, cpuid_AVX) && osSupportsAVX
|
||||
|
||||
if maxID < 7 {
|
||||
return
|
||||
}
|
||||
|
||||
eax7, ebx7, ecx7, edx7 := cpuid(7, 0)
|
||||
X86.HasBMI1 = isSet(ebx7, cpuid_BMI1)
|
||||
X86.HasAVX2 = isSet(ebx7, cpuid_AVX2) && osSupportsAVX
|
||||
X86.HasBMI2 = isSet(ebx7, cpuid_BMI2)
|
||||
X86.HasERMS = isSet(ebx7, cpuid_ERMS)
|
||||
X86.HasRDSEED = isSet(ebx7, cpuid_RDSEED)
|
||||
X86.HasADX = isSet(ebx7, cpuid_ADX)
|
||||
|
||||
X86.HasAVX512 = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512 // Because avx-512 foundation is the core required extension
|
||||
if X86.HasAVX512 {
|
||||
X86.HasAVX512F = true
|
||||
X86.HasAVX512CD = isSet(ebx7, cpuid_AVX512CD)
|
||||
X86.HasAVX512ER = isSet(ebx7, cpuid_AVX512ER)
|
||||
X86.HasAVX512PF = isSet(ebx7, cpuid_AVX512PF)
|
||||
X86.HasAVX512VL = isSet(ebx7, cpuid_AVX512VL)
|
||||
X86.HasAVX512BW = isSet(ebx7, cpuid_AVX512BW)
|
||||
X86.HasAVX512DQ = isSet(ebx7, cpuid_AVX512DQ)
|
||||
X86.HasAVX512IFMA = isSet(ebx7, cpuid_AVX512IFMA)
|
||||
X86.HasAVX512VBMI = isSet(ecx7, cpuid_AVX512_VBMI)
|
||||
X86.HasAVX5124VNNIW = isSet(edx7, cpuid_AVX5124VNNIW)
|
||||
X86.HasAVX5124FMAPS = isSet(edx7, cpuid_AVX5124FMAPS)
|
||||
X86.HasAVX512VPOPCNTDQ = isSet(ecx7, cpuid_AVX512VPOPCNTDQ)
|
||||
X86.HasAVX512VPCLMULQDQ = isSet(ecx7, cpuid_AVX512VPCLMULQDQ)
|
||||
X86.HasAVX512VNNI = isSet(ecx7, cpuid_AVX512VNNI)
|
||||
X86.HasAVX512GFNI = isSet(ecx7, cpuid_AVX512GFNI)
|
||||
X86.HasAVX512VAES = isSet(ecx7, cpuid_AVX512VAES)
|
||||
X86.HasAVX512VBMI2 = isSet(ecx7, cpuid_AVX512VBMI2)
|
||||
X86.HasAVX512BITALG = isSet(ecx7, cpuid_AVX512BITALG)
|
||||
}
|
||||
|
||||
X86.HasAMXTile = isSet(edx7, cpuid_AMXTile)
|
||||
X86.HasAMXInt8 = isSet(edx7, cpuid_AMXInt8)
|
||||
X86.HasAMXBF16 = isSet(edx7, cpuid_AMXBF16)
|
||||
|
||||
// These features depend on the second level of extended features.
|
||||
if eax7 >= 1 {
|
||||
eax71, _, _, edx71 := cpuid(7, 1)
|
||||
if X86.HasAVX512 {
|
||||
X86.HasAVX512BF16 = isSet(eax71, cpuid_AVX512BF16)
|
||||
}
|
||||
if X86.HasAVX {
|
||||
X86.HasAVXIFMA = isSet(eax71, cpuid_AVXIFMA)
|
||||
X86.HasAVXVNNI = isSet(eax71, cpuid_AVXVNNI)
|
||||
X86.HasAVXVNNIInt8 = isSet(edx71, cpuid_AVXVNNIInt8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isSet(hwc uint32, value uint32) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// Copyright 2020 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 cpu
|
||||
|
||||
func archInit() {
|
||||
doinit()
|
||||
Initialized = true
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright 2020 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 cpu
|
||||
|
||||
func initS390Xbase() {
|
||||
// get the facilities list
|
||||
facilities := stfle()
|
||||
|
||||
// mandatory
|
||||
S390X.HasZARCH = facilities.Has(zarch)
|
||||
S390X.HasSTFLE = facilities.Has(stflef)
|
||||
S390X.HasLDISP = facilities.Has(ldisp)
|
||||
S390X.HasEIMM = facilities.Has(eimm)
|
||||
|
||||
// optional
|
||||
S390X.HasETF3EH = facilities.Has(etf3eh)
|
||||
S390X.HasDFP = facilities.Has(dfp)
|
||||
S390X.HasMSA = facilities.Has(msa)
|
||||
S390X.HasVX = facilities.Has(vx)
|
||||
if S390X.HasVX {
|
||||
S390X.HasVXE = facilities.Has(vxe)
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// 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.
|
||||
|
||||
//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64
|
||||
|
||||
package cpu
|
||||
|
||||
// IsBigEndian records whether the GOARCH's byte order is big endian.
|
||||
const IsBigEndian = true
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// 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.
|
||||
|
||||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm
|
||||
|
||||
package cpu
|
||||
|
||||
// IsBigEndian records whether the GOARCH's byte order is big endian.
|
||||
const IsBigEndian = false
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// 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.
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
_AT_HWCAP = 16
|
||||
_AT_HWCAP2 = 26
|
||||
|
||||
procAuxv = "/proc/self/auxv"
|
||||
|
||||
uintSize = int(32 << (^uint(0) >> 63))
|
||||
)
|
||||
|
||||
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||
// These are initialized in cpu_$GOARCH.go
|
||||
// and should not be changed after they are initialized.
|
||||
var hwCap uint
|
||||
var hwCap2 uint
|
||||
|
||||
func readHWCAP() error {
|
||||
// For Go 1.21+, get auxv from the Go runtime.
|
||||
if a := getAuxv(); len(a) > 0 {
|
||||
for len(a) >= 2 {
|
||||
tag, val := a[0], uint(a[1])
|
||||
a = a[2:]
|
||||
switch tag {
|
||||
case _AT_HWCAP:
|
||||
hwCap = val
|
||||
case _AT_HWCAP2:
|
||||
hwCap2 = val
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
buf, err := os.ReadFile(procAuxv)
|
||||
if err != nil {
|
||||
// e.g. on android /proc/self/auxv is not accessible, so silently
|
||||
// ignore the error and leave Initialized = false. On some
|
||||
// architectures (e.g. arm64) doinit() implements a fallback
|
||||
// readout and will set Initialized = true again.
|
||||
return err
|
||||
}
|
||||
bo := hostByteOrder()
|
||||
for len(buf) >= 2*(uintSize/8) {
|
||||
var tag, val uint
|
||||
switch uintSize {
|
||||
case 32:
|
||||
tag = uint(bo.Uint32(buf[0:]))
|
||||
val = uint(bo.Uint32(buf[4:]))
|
||||
buf = buf[8:]
|
||||
case 64:
|
||||
tag = uint(bo.Uint64(buf[0:]))
|
||||
val = uint(bo.Uint64(buf[8:]))
|
||||
buf = buf[16:]
|
||||
}
|
||||
switch tag {
|
||||
case _AT_HWCAP:
|
||||
hwCap = val
|
||||
case _AT_HWCAP2:
|
||||
hwCap2 = val
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright 2022 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 cpu
|
||||
|
||||
import "strconv"
|
||||
|
||||
// parseRelease parses a dot-separated version number. It follows the semver
|
||||
// syntax, but allows the minor and patch versions to be elided.
|
||||
//
|
||||
// This is a copy of the Go runtime's parseRelease from
|
||||
// https://golang.org/cl/209597.
|
||||
func parseRelease(rel string) (major, minor, patch int, ok bool) {
|
||||
// Strip anything after a dash or plus.
|
||||
for i := range len(rel) {
|
||||
if rel[i] == '-' || rel[i] == '+' {
|
||||
rel = rel[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
next := func() (int, bool) {
|
||||
for i := range len(rel) {
|
||||
if rel[i] == '.' {
|
||||
ver, err := strconv.Atoi(rel[:i])
|
||||
rel = rel[i+1:]
|
||||
return ver, err == nil
|
||||
}
|
||||
}
|
||||
ver, err := strconv.Atoi(rel)
|
||||
rel = ""
|
||||
return ver, err == nil
|
||||
}
|
||||
if major, ok = next(); !ok || rel == "" {
|
||||
return
|
||||
}
|
||||
if minor, ok = next(); !ok || rel == "" {
|
||||
return
|
||||
}
|
||||
patch, ok = next()
|
||||
return
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Copyright 2022 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 linux && arm64
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func readLinuxProcCPUInfo() error {
|
||||
f, err := os.Open("/proc/cpuinfo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var buf [1 << 10]byte // enough for first CPU
|
||||
n, err := io.ReadFull(f, buf[:])
|
||||
if err != nil && err != io.ErrUnexpectedEOF {
|
||||
return err
|
||||
}
|
||||
in := string(buf[:n])
|
||||
const features = "\nFeatures : "
|
||||
i := strings.Index(in, features)
|
||||
if i == -1 {
|
||||
return errors.New("no CPU features found")
|
||||
}
|
||||
in = in[i+len(features):]
|
||||
if i := strings.Index(in, "\n"); i != -1 {
|
||||
in = in[:i]
|
||||
}
|
||||
m := map[string]*bool{}
|
||||
|
||||
initOptions() // need it early here; it's harmless to call twice
|
||||
for _, o := range options {
|
||||
m[o.Name] = o.Feature
|
||||
}
|
||||
// The EVTSTRM field has alias "evstrm" in Go, but Linux calls it "evtstrm".
|
||||
m["evtstrm"] = &ARM64.HasEVTSTRM
|
||||
|
||||
for _, f := range strings.Fields(in) {
|
||||
if p, ok := m[f]; ok {
|
||||
*p = true
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+16
@@ -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.
|
||||
|
||||
package cpu
|
||||
|
||||
// getAuxvFn is non-nil on Go 1.21+ (via runtime_auxv_go121.go init)
|
||||
// on platforms that use auxv.
|
||||
var getAuxvFn func() []uintptr
|
||||
|
||||
func getAuxv() []uintptr {
|
||||
if getAuxvFn == nil {
|
||||
return nil
|
||||
}
|
||||
return getAuxvFn()
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// 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.
|
||||
|
||||
//go:build go1.21
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
_ "unsafe" // for linkname
|
||||
)
|
||||
|
||||
//go:linkname runtime_getAuxv runtime.getAuxv
|
||||
func runtime_getAuxv() []uintptr
|
||||
|
||||
func init() {
|
||||
getAuxvFn = runtime_getAuxv
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
// Recreate a getsystemcfg syscall handler instead of
|
||||
// using the one provided by x/sys/unix to avoid having
|
||||
// the dependency between them. (See golang.org/issue/32102)
|
||||
// Moreover, this file will be used during the building of
|
||||
// gccgo's libgo and thus must not used a CGo method.
|
||||
|
||||
//go:build aix && gccgo
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
//extern getsystemcfg
|
||||
func gccgoGetsystemcfg(label uint32) (r uint64)
|
||||
|
||||
func callgetsystemcfg(label int) (r1 uintptr, e1 syscall.Errno) {
|
||||
r1 = uintptr(gccgoGetsystemcfg(uint32(label)))
|
||||
e1 = syscall.GetErrno()
|
||||
return
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
// Minimal copy of x/sys/unix so the cpu package can make a
|
||||
// system call on AIX without depending on x/sys/unix.
|
||||
// (See golang.org/issue/32102)
|
||||
|
||||
//go:build aix && ppc64 && gc
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o"
|
||||
|
||||
//go:linkname libc_getsystemcfg libc_getsystemcfg
|
||||
|
||||
type syscallFunc uintptr
|
||||
|
||||
var libc_getsystemcfg syscallFunc
|
||||
|
||||
type errno = syscall.Errno
|
||||
|
||||
// Implemented in runtime/syscall_aix.go.
|
||||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
|
||||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
|
||||
|
||||
func callgetsystemcfg(label int) (r1 uintptr, e1 errno) {
|
||||
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0)
|
||||
return
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// Copyright 2024 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.
|
||||
|
||||
// Minimal copy of x/sys/unix so the cpu package can make a
|
||||
// system call on Darwin without depending on x/sys/unix.
|
||||
|
||||
//go:build darwin && amd64 && gc
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type _C_int int32
|
||||
|
||||
// adapted from unix.Uname() at x/sys/unix/syscall_darwin.go L419
|
||||
func darwinOSRelease(release *[256]byte) error {
|
||||
// from x/sys/unix/zerrors_openbsd_amd64.go
|
||||
const (
|
||||
CTL_KERN = 0x1
|
||||
KERN_OSRELEASE = 0x2
|
||||
)
|
||||
|
||||
mib := []_C_int{CTL_KERN, KERN_OSRELEASE}
|
||||
n := unsafe.Sizeof(*release)
|
||||
|
||||
return sysctl(mib, &release[0], &n, nil, 0)
|
||||
}
|
||||
|
||||
type Errno = syscall.Errno
|
||||
|
||||
var _zero uintptr // Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||
|
||||
// from x/sys/unix/zsyscall_darwin_amd64.go L791-807
|
||||
func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(mib) > 0 {
|
||||
_p0 = unsafe.Pointer(&mib[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
if _, _, err := syscall_syscall6(
|
||||
libc_sysctl_trampoline_addr,
|
||||
uintptr(_p0),
|
||||
uintptr(len(mib)),
|
||||
uintptr(unsafe.Pointer(old)),
|
||||
uintptr(unsafe.Pointer(oldlen)),
|
||||
uintptr(unsafe.Pointer(new)),
|
||||
uintptr(newlen),
|
||||
); err != 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var libc_sysctl_trampoline_addr uintptr
|
||||
|
||||
// adapted from internal/cpu/cpu_arm64_darwin.go
|
||||
func darwinSysctlEnabled(name []byte) bool {
|
||||
out := int32(0)
|
||||
nout := unsafe.Sizeof(out)
|
||||
if ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); ret != nil {
|
||||
return false
|
||||
}
|
||||
return out > 0
|
||||
}
|
||||
|
||||
//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
var libc_sysctlbyname_trampoline_addr uintptr
|
||||
|
||||
// adapted from runtime/sys_darwin.go in the pattern of sysctl() above, as defined in x/sys/unix
|
||||
func sysctlbyname(name *byte, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {
|
||||
if _, _, err := syscall_syscall6(
|
||||
libc_sysctlbyname_trampoline_addr,
|
||||
uintptr(unsafe.Pointer(name)),
|
||||
uintptr(unsafe.Pointer(old)),
|
||||
uintptr(unsafe.Pointer(oldlen)),
|
||||
uintptr(unsafe.Pointer(new)),
|
||||
uintptr(newlen),
|
||||
0,
|
||||
); err != 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_darwin.go)
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's
|
||||
// slice and string implementations.
|
||||
//
|
||||
// This package allows x/sys to use types equivalent to
|
||||
// reflect.SliceHeader and reflect.StringHeader without introducing
|
||||
// a dependency on the (relatively heavy) "reflect" package.
|
||||
package unsafeheader
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Slice is the runtime representation of a slice.
|
||||
// It cannot be used safely or portably and its representation may change in a later release.
|
||||
type Slice struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
Cap int
|
||||
}
|
||||
|
||||
// String is the runtime representation of a string.
|
||||
// It cannot be used safely or portably and its representation may change in a later release.
|
||||
type String struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
}
|
||||
+1
-1
@@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these
|
||||
into a common file for each OS.
|
||||
|
||||
The merge is performed in the following steps:
|
||||
1. Construct the set of common code that is idential in all architecture-specific files.
|
||||
1. Construct the set of common code that is identical in all architecture-specific files.
|
||||
2. Write this common code to the merged file.
|
||||
3. Remove the common code from all architecture-specific files.
|
||||
|
||||
|
||||
+8
-1
@@ -38,8 +38,15 @@ func SchedSetaffinity(pid int, set *CPUSet) error {
|
||||
|
||||
// Zero clears the set s, so that it contains no CPUs.
|
||||
func (s *CPUSet) Zero() {
|
||||
clear(s[:])
|
||||
}
|
||||
|
||||
// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
|
||||
// will silently ignore any invalid CPU bits in [CPUSet] so this is an
|
||||
// efficient way of resetting the CPU affinity of a process.
|
||||
func (s *CPUSet) Fill() {
|
||||
for i := range s {
|
||||
s[i] = 0
|
||||
s[i] = ^cpuMask(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -2,9 +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 || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
// +build go1.9
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-2
@@ -3,8 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (freebsd || netbsd || openbsd) && gc
|
||||
// +build freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-2
@@ -3,8 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-2
@@ -3,8 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (freebsd || netbsd || openbsd) && gc
|
||||
// +build freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-2
@@ -3,8 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2022 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 (darwin || freebsd || netbsd || openbsd) && gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ppc64, BSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2021 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 (darwin || freebsd || netbsd || openbsd) && gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// System call support for RISCV64 BSD
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-3
@@ -3,9 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && arm64 && gc
|
||||
// +build linux
|
||||
// +build arm64
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright 2022 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 linux && loong64 && gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R11 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R4, r1+32(FP)
|
||||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R11 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R4, r1+32(FP)
|
||||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0
|
||||
RET
|
||||
-3
@@ -3,9 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (mips64 || mips64le) && gc
|
||||
// +build linux
|
||||
// +build mips64 mips64le
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-3
@@ -3,9 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (mips || mipsle) && gc
|
||||
// +build linux
|
||||
// +build mips mipsle
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-3
@@ -3,9 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (ppc64 || ppc64le) && gc
|
||||
// +build linux
|
||||
// +build ppc64 ppc64le
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-2
@@ -3,8 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build riscv64 && gc
|
||||
// +build riscv64
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-3
@@ -3,9 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && s390x && gc
|
||||
// +build linux
|
||||
// +build s390x
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build gc
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
+317
-361
@@ -3,18 +3,17 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x && gc
|
||||
// +build zos
|
||||
// +build s390x
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define PSALAA 1208(R0)
|
||||
#define GTAB64(x) 80(x)
|
||||
#define LCA64(x) 88(x)
|
||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
||||
#define CAA(x) 8(x)
|
||||
#define EDCHPXV(x) 1016(x) // in the CAA
|
||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
||||
#define CEECAATHDID(x) 976(x) // in the CAA
|
||||
#define EDCHPXV(x) 1016(x) // in the CAA
|
||||
#define GOCB(x) 1104(x) // in the CAA
|
||||
|
||||
// SS_*, where x=SAVSTACK_ASYNC
|
||||
#define SS_LE(x) 0(x)
|
||||
@@ -22,394 +21,125 @@
|
||||
#define SS_ERRNO(x) 16(x)
|
||||
#define SS_ERRNOJR(x) 20(x)
|
||||
|
||||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
||||
// Function Descriptor Offsets
|
||||
#define __errno 0x156*16
|
||||
#define __err2ad 0x16C*16
|
||||
|
||||
TEXT ·clearErrno(SB),NOSPLIT,$0-0
|
||||
BL addrerrno<>(SB)
|
||||
MOVD $0, 0(R3)
|
||||
// Call Instructions
|
||||
#define LE_CALL BYTE $0x0D; BYTE $0x76 // BL R7, R6
|
||||
#define SVC_LOAD BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
|
||||
#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
|
||||
|
||||
DATA zosLibVec<>(SB)/8, $0
|
||||
GLOBL zosLibVec<>(SB), NOPTR, $8
|
||||
|
||||
TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD CAA(R8), R8
|
||||
MOVD EDCHPXV(R8), R8
|
||||
MOVD R8, zosLibVec<>(SB)
|
||||
RET
|
||||
|
||||
TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD zosLibVec<>(SB), R8
|
||||
MOVD R8, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT ·clearErrno(SB), NOSPLIT, $0-0
|
||||
BL addrerrno<>(SB)
|
||||
MOVD $0, 0(R3)
|
||||
RET
|
||||
|
||||
// Returns the address of errno in R3.
|
||||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
||||
TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get __errno FuncDesc.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
ADD $(0x156*16), R9
|
||||
LMG 0(R9), R5, R6
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
ADD $(__errno), R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Switch to saved LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call __errno function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
|
||||
// Switch back to Go stack.
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R0, r2+40(FP)
|
||||
MOVD R0, err+48(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R0, r2+40(FP)
|
||||
MOVD R0, err+48(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
done:
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+56(FP)
|
||||
MOVD R0, r2+64(FP)
|
||||
MOVD R0, err+72(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+72(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+56(FP)
|
||||
MOVD R0, r2+64(FP)
|
||||
MOVD R0, err+72(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL ·rrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+72(FP)
|
||||
done:
|
||||
RET
|
||||
|
||||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
MOVD a7+56(FP), R12
|
||||
MOVD R12, (2176+48)(R4)
|
||||
MOVD a8+64(FP), R12
|
||||
MOVD R12, (2176+56)(R4)
|
||||
MOVD a9+72(FP), R12
|
||||
MOVD R12, (2176+64)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+80(FP)
|
||||
MOVD R0, r2+88(FP)
|
||||
MOVD R0, err+96(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+96(FP)
|
||||
done:
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
|
||||
MOVD a1+8(FP), R1
|
||||
MOVD a2+16(FP), R2
|
||||
MOVD a3+24(FP), R3
|
||||
|
||||
// Get library control area (LCA).
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
|
||||
// Get function.
|
||||
MOVD CAA(R8), R9
|
||||
MOVD EDCHPXV(R9), R9
|
||||
MOVD trap+0(FP), R5
|
||||
SLD $4, R5
|
||||
ADD R5, R9
|
||||
LMG 0(R9), R5, R6
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R4
|
||||
MOVD $0, 0(R9)
|
||||
|
||||
// Fill in parameter list.
|
||||
MOVD a4+32(FP), R12
|
||||
MOVD R12, (2176+24)(R4)
|
||||
MOVD a5+40(FP), R12
|
||||
MOVD R12, (2176+32)(R4)
|
||||
MOVD a6+48(FP), R12
|
||||
MOVD R12, (2176+40)(R4)
|
||||
MOVD a7+56(FP), R12
|
||||
MOVD R12, (2176+48)(R4)
|
||||
MOVD a8+64(FP), R12
|
||||
MOVD R12, (2176+56)(R4)
|
||||
MOVD a9+72(FP), R12
|
||||
MOVD R12, (2176+64)(R4)
|
||||
|
||||
// Call function.
|
||||
LE_CALL
|
||||
NOPH
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
|
||||
MOVD R3, r1+80(FP)
|
||||
MOVD R0, r2+88(FP)
|
||||
MOVD R0, err+96(FP)
|
||||
MOVW R3, R4
|
||||
CMP R4, $-1
|
||||
BNE done
|
||||
BL addrerrno<>(SB)
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+96(FP)
|
||||
done:
|
||||
XOR R0, R0 // Restore R0 to $0.
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
RET
|
||||
|
||||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
||||
TEXT ·svcCall(SB),NOSPLIT,$0
|
||||
BL runtime·save_g(SB) // Save g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD R15, 0(R9)
|
||||
TEXT ·svcCall(SB), NOSPLIT, $0
|
||||
BL runtime·save_g(SB) // Save g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD R15, 0(R9)
|
||||
|
||||
MOVD argv+8(FP), R1 // Move function arguments into registers
|
||||
MOVD dsa+16(FP), g
|
||||
MOVD fnptr+0(FP), R15
|
||||
MOVD argv+8(FP), R1 // Move function arguments into registers
|
||||
MOVD dsa+16(FP), g
|
||||
MOVD fnptr+0(FP), R15
|
||||
|
||||
BYTE $0x0D // Branch to function
|
||||
BYTE $0xEF
|
||||
BYTE $0x0D // Branch to function
|
||||
BYTE $0xEF
|
||||
|
||||
BL runtime·load_g(SB) // Restore g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R15
|
||||
BL runtime·load_g(SB) // Restore g and stack pointer
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD SAVSTACK_ASYNC(R8), R9
|
||||
MOVD 0(R9), R15
|
||||
|
||||
RET
|
||||
|
||||
// func svcLoad(name *byte) unsafe.Pointer
|
||||
TEXT ·svcLoad(SB),NOSPLIT,$0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD $0x80000000, R1
|
||||
MOVD $0, R15
|
||||
BYTE $0x0A // SVC 08 LOAD
|
||||
BYTE $0x08
|
||||
MOVW R15, R3 // Save return code from SVC
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
CMP R3, $0 // Check SVC return code
|
||||
BNE error
|
||||
TEXT ·svcLoad(SB), NOSPLIT, $0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD $0x80000000, R1
|
||||
MOVD $0, R15
|
||||
SVC_LOAD
|
||||
MOVW R15, R3 // Save return code from SVC
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
CMP R3, $0 // Check SVC return code
|
||||
BNE error
|
||||
|
||||
MOVD $-2, R3 // Reset last bit of entry point to zero
|
||||
AND R0, R3
|
||||
MOVD R3, addr+8(FP) // Return entry point returned by SVC
|
||||
CMP R0, R3 // Check if last bit of entry point was set
|
||||
BNE done
|
||||
MOVD $-2, R3 // Reset last bit of entry point to zero
|
||||
AND R0, R3
|
||||
MOVD R3, ret+8(FP) // Return entry point returned by SVC
|
||||
CMP R0, R3 // Check if last bit of entry point was set
|
||||
BNE done
|
||||
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
||||
BYTE $0x0A // SVC 09 DELETE
|
||||
BYTE $0x09
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
||||
SVC_DELETE
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
|
||||
error:
|
||||
MOVD $0, addr+8(FP) // Return 0 on failure
|
||||
MOVD $0, ret+8(FP) // Return 0 on failure
|
||||
|
||||
done:
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
RET
|
||||
|
||||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
||||
TEXT ·svcUnload(SB),NOSPLIT,$0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD addr+8(FP), R15
|
||||
BYTE $0x0A // SVC 09
|
||||
BYTE $0x09
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
MOVD R15, R1 // Save SVC return code
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
MOVD R1, rc+0(FP) // Return SVC return code
|
||||
TEXT ·svcUnload(SB), NOSPLIT, $0
|
||||
MOVD R15, R2 // Save go stack pointer
|
||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||
MOVD fnptr+8(FP), R15
|
||||
SVC_DELETE
|
||||
XOR R0, R0 // Reset r0 to 0
|
||||
MOVD R15, R1 // Save SVC return code
|
||||
MOVD R2, R15 // Restore go stack pointer
|
||||
MOVD R1, ret+16(FP) // Return SVC return code
|
||||
RET
|
||||
|
||||
// func gettid() uint64
|
||||
@@ -420,7 +150,233 @@ TEXT ·gettid(SB), NOSPLIT, $0
|
||||
|
||||
// Get CEECAATHDID
|
||||
MOVD CAA(R8), R9
|
||||
MOVD 0x3D0(R9), R9
|
||||
MOVD CEECAATHDID(R9), R9
|
||||
MOVD R9, ret+0(FP)
|
||||
|
||||
RET
|
||||
|
||||
//
|
||||
// Call LE function, if the return is -1
|
||||
// errno and errno2 is retrieved
|
||||
//
|
||||
TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD CAA(R8), R9
|
||||
MOVD g, GOCB(R9)
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
||||
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
||||
|
||||
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
||||
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
||||
|
||||
// arg 1 ---> R1
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
MOVD 0(R7), R1
|
||||
|
||||
// arg 2 ---> R2
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R2
|
||||
|
||||
// arg 3 --> R3
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R3
|
||||
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
||||
|
||||
repeat:
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
||||
ADD $8, R6 // advance LE argument address by 8 byte
|
||||
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
||||
SUB $1, R8
|
||||
CMP R8, $0
|
||||
BNE repeat
|
||||
|
||||
docall:
|
||||
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
||||
LMG 0(R8), R5, R6
|
||||
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
||||
LE_CALL // balr R7, R6 (return #1)
|
||||
NOPH
|
||||
MOVD R3, ret+32(FP)
|
||||
CMP R3, $-1 // compare result to -1
|
||||
BNE done
|
||||
|
||||
// retrieve errno and errno2
|
||||
MOVD zosLibVec<>(SB), R8
|
||||
ADD $(__errno), R8
|
||||
LMG 0(R8), R5, R6
|
||||
LE_CALL // balr R7, R6 __errno (return #3)
|
||||
NOPH
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
MOVD zosLibVec<>(SB), R8
|
||||
ADD $(__err2ad), R8
|
||||
LMG 0(R8), R5, R6
|
||||
LE_CALL // balr R7, R6 __err2ad (return #2)
|
||||
NOPH
|
||||
MOVW (R3), R2 // retrieve errno2
|
||||
MOVD R2, errno2+40(FP) // store in return area
|
||||
|
||||
done:
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
RET
|
||||
|
||||
//
|
||||
// Call LE function, if the return is 0
|
||||
// errno and errno2 is retrieved
|
||||
//
|
||||
TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
|
||||
MOVW PSALAA, R8
|
||||
MOVD LCA64(R8), R8
|
||||
MOVD CAA(R8), R9
|
||||
MOVD g, GOCB(R9)
|
||||
|
||||
// Restore LE stack.
|
||||
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
||||
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
||||
|
||||
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
||||
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
||||
|
||||
// arg 1 ---> R1
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
MOVD 0(R7), R1
|
||||
|
||||
// arg 2 ---> R2
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R2
|
||||
|
||||
// arg 3 --> R3
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
SUB $1, R8
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R3
|
||||
|
||||
CMP R8, $0
|
||||
BEQ docall
|
||||
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
||||
|
||||
repeat:
|
||||
ADD $8, R7
|
||||
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
||||
ADD $8, R6 // advance LE argument address by 8 byte
|
||||
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
||||
SUB $1, R8
|
||||
CMP R8, $0
|
||||
BNE repeat
|
||||
|
||||
docall:
|
||||
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
||||
LMG 0(R8), R5, R6
|
||||
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
||||
LE_CALL // balr R7, R6 (return #1)
|
||||
NOPH
|
||||
MOVD R3, ret+32(FP)
|
||||
CMP R3, $0 // compare result to 0
|
||||
BNE done
|
||||
|
||||
// retrieve errno and errno2
|
||||
MOVD zosLibVec<>(SB), R8
|
||||
ADD $(__errno), R8
|
||||
LMG 0(R8), R5, R6
|
||||
LE_CALL // balr R7, R6 __errno (return #3)
|
||||
NOPH
|
||||
MOVWZ 0(R3), R3
|
||||
MOVD R3, err+48(FP)
|
||||
MOVD zosLibVec<>(SB), R8
|
||||
ADD $(__err2ad), R8
|
||||
LMG 0(R8), R5, R6
|
||||
LE_CALL // balr R7, R6 __err2ad (return #2)
|
||||
NOPH
|
||||
MOVW (R3), R2 // retrieve errno2
|
||||
MOVD R2, errno2+40(FP) // store in return area
|
||||
XOR R2, R2
|
||||
MOVWZ R2, (R3) // clear errno2
|
||||
|
||||
done:
|
||||
MOVD R4, 0(R9) // Save stack pointer.
|
||||
RET
|
||||
|
||||
//
|
||||
// function to test if a pointer can be safely dereferenced (content read)
|
||||
// return 0 for succces
|
||||
//
|
||||
TEXT ·ptrtest(SB), NOSPLIT, $0-16
|
||||
MOVD arg+0(FP), R10 // test pointer in R10
|
||||
|
||||
// set up R2 to point to CEECAADMC
|
||||
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
||||
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
||||
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
||||
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
||||
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
||||
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
||||
|
||||
// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
|
||||
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
||||
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
||||
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
||||
|
||||
// if r3 is not zero (failed) then branch to finish
|
||||
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
||||
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
||||
|
||||
// stomic store shunt address in R5 into CEECAADMC
|
||||
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
||||
|
||||
// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
|
||||
BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 9,0(10)
|
||||
|
||||
// finish here, restore 0 into CEECAADMC
|
||||
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
||||
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
||||
MOVD R3, ret+8(FP) // result in R3
|
||||
RET
|
||||
|
||||
//
|
||||
// function to test if a untptr can be loaded from a pointer
|
||||
// return 1: the 8-byte content
|
||||
// 2: 0 for success, 1 for failure
|
||||
//
|
||||
// func safeload(ptr uintptr) ( value uintptr, error uintptr)
|
||||
TEXT ·safeload(SB), NOSPLIT, $0-24
|
||||
MOVD ptr+0(FP), R10 // test pointer in R10
|
||||
MOVD $0x0, R6
|
||||
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
||||
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
||||
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
||||
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
||||
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
||||
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
||||
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
||||
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
||||
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
||||
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
||||
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
||||
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
||||
BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 6,0(10)
|
||||
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
||||
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
||||
MOVD R6, value+8(FP) // result in R6
|
||||
MOVD R3, error+16(FP) // error in R3
|
||||
RET
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2025 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 go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname runtime_getAuxv runtime.getAuxv
|
||||
func runtime_getAuxv() []uintptr
|
||||
|
||||
// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs.
|
||||
// The returned slice is always a fresh copy, owned by the caller.
|
||||
// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed,
|
||||
// which happens in some locked-down environments and build modes.
|
||||
func Auxv() ([][2]uintptr, error) {
|
||||
vec := runtime_getAuxv()
|
||||
vecLen := len(vec)
|
||||
|
||||
if vecLen == 0 {
|
||||
return nil, syscall.ENOENT
|
||||
}
|
||||
|
||||
if vecLen%2 != 0 {
|
||||
return nil, syscall.EINVAL
|
||||
}
|
||||
|
||||
result := make([]uintptr, vecLen)
|
||||
copy(result, vec)
|
||||
return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Copyright 2025 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 !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
func Auxv() ([][2]uintptr, error) {
|
||||
return nil, syscall.ENOTSUP
|
||||
}
|
||||
+657
@@ -0,0 +1,657 @@
|
||||
// Copyright 2024 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 zos
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
|
||||
|
||||
//go:noescape
|
||||
func A2e([]byte)
|
||||
|
||||
//go:noescape
|
||||
func E2a([]byte)
|
||||
|
||||
const (
|
||||
BPX4STA = 192 // stat
|
||||
BPX4FST = 104 // fstat
|
||||
BPX4LST = 132 // lstat
|
||||
BPX4OPN = 156 // open
|
||||
BPX4CLO = 72 // close
|
||||
BPX4CHR = 500 // chattr
|
||||
BPX4FCR = 504 // fchattr
|
||||
BPX4LCR = 1180 // lchattr
|
||||
BPX4CTW = 492 // cond_timed_wait
|
||||
BPX4GTH = 1056 // __getthent
|
||||
BPX4PTQ = 412 // pthread_quiesc
|
||||
BPX4PTR = 320 // ptrace
|
||||
)
|
||||
|
||||
const (
|
||||
//options
|
||||
//byte1
|
||||
BPX_OPNFHIGH = 0x80
|
||||
//byte2
|
||||
BPX_OPNFEXEC = 0x80
|
||||
//byte3
|
||||
BPX_O_NOLARGEFILE = 0x08
|
||||
BPX_O_LARGEFILE = 0x04
|
||||
BPX_O_ASYNCSIG = 0x02
|
||||
BPX_O_SYNC = 0x01
|
||||
//byte4
|
||||
BPX_O_CREXCL = 0xc0
|
||||
BPX_O_CREAT = 0x80
|
||||
BPX_O_EXCL = 0x40
|
||||
BPX_O_NOCTTY = 0x20
|
||||
BPX_O_TRUNC = 0x10
|
||||
BPX_O_APPEND = 0x08
|
||||
BPX_O_NONBLOCK = 0x04
|
||||
BPX_FNDELAY = 0x04
|
||||
BPX_O_RDWR = 0x03
|
||||
BPX_O_RDONLY = 0x02
|
||||
BPX_O_WRONLY = 0x01
|
||||
BPX_O_ACCMODE = 0x03
|
||||
BPX_O_GETFL = 0x0f
|
||||
|
||||
//mode
|
||||
// byte1 (file type)
|
||||
BPX_FT_DIR = 1
|
||||
BPX_FT_CHARSPEC = 2
|
||||
BPX_FT_REGFILE = 3
|
||||
BPX_FT_FIFO = 4
|
||||
BPX_FT_SYMLINK = 5
|
||||
BPX_FT_SOCKET = 6
|
||||
//byte3
|
||||
BPX_S_ISUID = 0x08
|
||||
BPX_S_ISGID = 0x04
|
||||
BPX_S_ISVTX = 0x02
|
||||
BPX_S_IRWXU1 = 0x01
|
||||
BPX_S_IRUSR = 0x01
|
||||
//byte4
|
||||
BPX_S_IRWXU2 = 0xc0
|
||||
BPX_S_IWUSR = 0x80
|
||||
BPX_S_IXUSR = 0x40
|
||||
BPX_S_IRWXG = 0x38
|
||||
BPX_S_IRGRP = 0x20
|
||||
BPX_S_IWGRP = 0x10
|
||||
BPX_S_IXGRP = 0x08
|
||||
BPX_S_IRWXOX = 0x07
|
||||
BPX_S_IROTH = 0x04
|
||||
BPX_S_IWOTH = 0x02
|
||||
BPX_S_IXOTH = 0x01
|
||||
|
||||
CW_INTRPT = 1
|
||||
CW_CONDVAR = 32
|
||||
CW_TIMEOUT = 64
|
||||
|
||||
PGTHA_NEXT = 2
|
||||
PGTHA_CURRENT = 1
|
||||
PGTHA_FIRST = 0
|
||||
PGTHA_LAST = 3
|
||||
PGTHA_PROCESS = 0x80
|
||||
PGTHA_CONTTY = 0x40
|
||||
PGTHA_PATH = 0x20
|
||||
PGTHA_COMMAND = 0x10
|
||||
PGTHA_FILEDATA = 0x08
|
||||
PGTHA_THREAD = 0x04
|
||||
PGTHA_PTAG = 0x02
|
||||
PGTHA_COMMANDLONG = 0x01
|
||||
PGTHA_THREADFAST = 0x80
|
||||
PGTHA_FILEPATH = 0x40
|
||||
PGTHA_THDSIGMASK = 0x20
|
||||
// thread quiece mode
|
||||
QUIESCE_TERM int32 = 1
|
||||
QUIESCE_FORCE int32 = 2
|
||||
QUIESCE_QUERY int32 = 3
|
||||
QUIESCE_FREEZE int32 = 4
|
||||
QUIESCE_UNFREEZE int32 = 5
|
||||
FREEZE_THIS_THREAD int32 = 6
|
||||
FREEZE_EXIT int32 = 8
|
||||
QUIESCE_SRB int32 = 9
|
||||
)
|
||||
|
||||
type Pgtha struct {
|
||||
Pid uint32 // 0
|
||||
Tid0 uint32 // 4
|
||||
Tid1 uint32
|
||||
Accesspid byte // C
|
||||
Accesstid byte // D
|
||||
Accessasid uint16 // E
|
||||
Loginname [8]byte // 10
|
||||
Flag1 byte // 18
|
||||
Flag1b2 byte // 19
|
||||
}
|
||||
|
||||
type Bpxystat_t struct { // DSECT BPXYSTAT
|
||||
St_id [4]uint8 // 0
|
||||
St_length uint16 // 0x4
|
||||
St_version uint16 // 0x6
|
||||
St_mode uint32 // 0x8
|
||||
St_ino uint32 // 0xc
|
||||
St_dev uint32 // 0x10
|
||||
St_nlink uint32 // 0x14
|
||||
St_uid uint32 // 0x18
|
||||
St_gid uint32 // 0x1c
|
||||
St_size uint64 // 0x20
|
||||
St_atime uint32 // 0x28
|
||||
St_mtime uint32 // 0x2c
|
||||
St_ctime uint32 // 0x30
|
||||
St_rdev uint32 // 0x34
|
||||
St_auditoraudit uint32 // 0x38
|
||||
St_useraudit uint32 // 0x3c
|
||||
St_blksize uint32 // 0x40
|
||||
St_createtime uint32 // 0x44
|
||||
St_auditid [4]uint32 // 0x48
|
||||
St_res01 uint32 // 0x58
|
||||
Ft_ccsid uint16 // 0x5c
|
||||
Ft_flags uint16 // 0x5e
|
||||
St_res01a [2]uint32 // 0x60
|
||||
St_res02 uint32 // 0x68
|
||||
St_blocks uint32 // 0x6c
|
||||
St_opaque [3]uint8 // 0x70
|
||||
St_visible uint8 // 0x73
|
||||
St_reftime uint32 // 0x74
|
||||
St_fid uint64 // 0x78
|
||||
St_filefmt uint8 // 0x80
|
||||
St_fspflag2 uint8 // 0x81
|
||||
St_res03 [2]uint8 // 0x82
|
||||
St_ctimemsec uint32 // 0x84
|
||||
St_seclabel [8]uint8 // 0x88
|
||||
St_res04 [4]uint8 // 0x90
|
||||
// end of version 1
|
||||
_ uint32 // 0x94
|
||||
St_atime64 uint64 // 0x98
|
||||
St_mtime64 uint64 // 0xa0
|
||||
St_ctime64 uint64 // 0xa8
|
||||
St_createtime64 uint64 // 0xb0
|
||||
St_reftime64 uint64 // 0xb8
|
||||
_ uint64 // 0xc0
|
||||
St_res05 [16]uint8 // 0xc8
|
||||
// end of version 2
|
||||
}
|
||||
|
||||
type BpxFilestatus struct {
|
||||
Oflag1 byte
|
||||
Oflag2 byte
|
||||
Oflag3 byte
|
||||
Oflag4 byte
|
||||
}
|
||||
|
||||
type BpxMode struct {
|
||||
Ftype byte
|
||||
Mode1 byte
|
||||
Mode2 byte
|
||||
Mode3 byte
|
||||
}
|
||||
|
||||
// Thr attribute structure for extended attributes
|
||||
type Bpxyatt_t struct { // DSECT BPXYATT
|
||||
Att_id [4]uint8
|
||||
Att_version uint16
|
||||
Att_res01 [2]uint8
|
||||
Att_setflags1 uint8
|
||||
Att_setflags2 uint8
|
||||
Att_setflags3 uint8
|
||||
Att_setflags4 uint8
|
||||
Att_mode uint32
|
||||
Att_uid uint32
|
||||
Att_gid uint32
|
||||
Att_opaquemask [3]uint8
|
||||
Att_visblmaskres uint8
|
||||
Att_opaque [3]uint8
|
||||
Att_visibleres uint8
|
||||
Att_size_h uint32
|
||||
Att_size_l uint32
|
||||
Att_atime uint32
|
||||
Att_mtime uint32
|
||||
Att_auditoraudit uint32
|
||||
Att_useraudit uint32
|
||||
Att_ctime uint32
|
||||
Att_reftime uint32
|
||||
// end of version 1
|
||||
Att_filefmt uint8
|
||||
Att_res02 [3]uint8
|
||||
Att_filetag uint32
|
||||
Att_res03 [8]uint8
|
||||
// end of version 2
|
||||
Att_atime64 uint64
|
||||
Att_mtime64 uint64
|
||||
Att_ctime64 uint64
|
||||
Att_reftime64 uint64
|
||||
Att_seclabel [8]uint8
|
||||
Att_ver3res02 [8]uint8
|
||||
// end of version 3
|
||||
}
|
||||
|
||||
func BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {
|
||||
if len(name) < 1024 {
|
||||
var namebuf [1024]byte
|
||||
sz := int32(copy(namebuf[:], name))
|
||||
A2e(namebuf[:sz])
|
||||
var parms [7]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sz)
|
||||
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||
parms[2] = unsafe.Pointer(options)
|
||||
parms[3] = unsafe.Pointer(mode)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4OPN)
|
||||
return rv, rc, rn
|
||||
}
|
||||
return -1, -1, -1
|
||||
}
|
||||
|
||||
func BpxClose(fd int32) (rv int32, rc int32, rn int32) {
|
||||
var parms [4]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&fd)
|
||||
parms[1] = unsafe.Pointer(&rv)
|
||||
parms[2] = unsafe.Pointer(&rc)
|
||||
parms[3] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4CLO)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||
st.St_version = 2
|
||||
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||
var parms [6]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&fd)
|
||||
parms[1] = unsafe.Pointer(&stat_sz)
|
||||
parms[2] = unsafe.Pointer(st)
|
||||
parms[3] = unsafe.Pointer(&rv)
|
||||
parms[4] = unsafe.Pointer(&rc)
|
||||
parms[5] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4FST)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||
if len(name) < 1024 {
|
||||
var namebuf [1024]byte
|
||||
sz := int32(copy(namebuf[:], name))
|
||||
A2e(namebuf[:sz])
|
||||
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||
st.St_version = 2
|
||||
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||
var parms [7]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sz)
|
||||
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||
parms[2] = unsafe.Pointer(&stat_sz)
|
||||
parms[3] = unsafe.Pointer(st)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4STA)
|
||||
return rv, rc, rn
|
||||
}
|
||||
return -1, -1, -1
|
||||
}
|
||||
|
||||
func BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||
if len(name) < 1024 {
|
||||
var namebuf [1024]byte
|
||||
sz := int32(copy(namebuf[:], name))
|
||||
A2e(namebuf[:sz])
|
||||
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||
st.St_version = 2
|
||||
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||
var parms [7]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sz)
|
||||
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||
parms[2] = unsafe.Pointer(&stat_sz)
|
||||
parms[3] = unsafe.Pointer(st)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4LST)
|
||||
return rv, rc, rn
|
||||
}
|
||||
return -1, -1, -1
|
||||
}
|
||||
|
||||
func BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||
if len(path) >= 1024 {
|
||||
return -1, -1, -1
|
||||
}
|
||||
var namebuf [1024]byte
|
||||
sz := int32(copy(namebuf[:], path))
|
||||
A2e(namebuf[:sz])
|
||||
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||
var parms [7]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sz)
|
||||
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||
parms[2] = unsafe.Pointer(&attr_sz)
|
||||
parms[3] = unsafe.Pointer(attr)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4CHR)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||
if len(path) >= 1024 {
|
||||
return -1, -1, -1
|
||||
}
|
||||
var namebuf [1024]byte
|
||||
sz := int32(copy(namebuf[:], path))
|
||||
A2e(namebuf[:sz])
|
||||
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||
var parms [7]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sz)
|
||||
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||
parms[2] = unsafe.Pointer(&attr_sz)
|
||||
parms[3] = unsafe.Pointer(attr)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4LCR)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||
var parms [6]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&fd)
|
||||
parms[1] = unsafe.Pointer(&attr_sz)
|
||||
parms[2] = unsafe.Pointer(attr)
|
||||
parms[3] = unsafe.Pointer(&rv)
|
||||
parms[4] = unsafe.Pointer(&rc)
|
||||
parms[5] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4FCR)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {
|
||||
var parms [8]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&sec)
|
||||
parms[1] = unsafe.Pointer(&nsec)
|
||||
parms[2] = unsafe.Pointer(&events)
|
||||
parms[3] = unsafe.Pointer(secrem)
|
||||
parms[4] = unsafe.Pointer(nsecrem)
|
||||
parms[5] = unsafe.Pointer(&rv)
|
||||
parms[6] = unsafe.Pointer(&rc)
|
||||
parms[7] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4CTW)
|
||||
return rv, rc, rn
|
||||
}
|
||||
func BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {
|
||||
var parms [7]unsafe.Pointer
|
||||
inlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is "packed" and must be 26-byte
|
||||
parms[0] = unsafe.Pointer(&inlen)
|
||||
parms[1] = unsafe.Pointer(&in)
|
||||
parms[2] = unsafe.Pointer(outlen)
|
||||
parms[3] = unsafe.Pointer(&out)
|
||||
parms[4] = unsafe.Pointer(&rv)
|
||||
parms[5] = unsafe.Pointer(&rc)
|
||||
parms[6] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4GTH)
|
||||
return rv, rc, rn
|
||||
}
|
||||
func ZosJobname() (jobname string, err error) {
|
||||
var pgtha Pgtha
|
||||
pgtha.Pid = uint32(Getpid())
|
||||
pgtha.Accesspid = PGTHA_CURRENT
|
||||
pgtha.Flag1 = PGTHA_PROCESS
|
||||
var out [256]byte
|
||||
var outlen uint32
|
||||
outlen = 256
|
||||
rv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))
|
||||
if rv == 0 {
|
||||
gthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic
|
||||
ix := bytes.Index(out[:], gthc)
|
||||
if ix == -1 {
|
||||
err = fmt.Errorf("BPX4GTH: gthc return data not found")
|
||||
return
|
||||
}
|
||||
jn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80
|
||||
E2a(jn)
|
||||
jobname = string(bytes.TrimRight(jn, " "))
|
||||
|
||||
} else {
|
||||
err = fmt.Errorf("BPX4GTH: rc=%d errno=%d reason=code=0x%x", rv, rc, rn)
|
||||
}
|
||||
return
|
||||
}
|
||||
func Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {
|
||||
var userdata [8]byte
|
||||
var parms [5]unsafe.Pointer
|
||||
copy(userdata[:], data+" ")
|
||||
A2e(userdata[:])
|
||||
parms[0] = unsafe.Pointer(&code)
|
||||
parms[1] = unsafe.Pointer(&userdata[0])
|
||||
parms[2] = unsafe.Pointer(&rv)
|
||||
parms[3] = unsafe.Pointer(&rc)
|
||||
parms[4] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4PTQ)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
const (
|
||||
PT_TRACE_ME = 0 // Debug this process
|
||||
PT_READ_I = 1 // Read a full word
|
||||
PT_READ_D = 2 // Read a full word
|
||||
PT_READ_U = 3 // Read control info
|
||||
PT_WRITE_I = 4 //Write a full word
|
||||
PT_WRITE_D = 5 //Write a full word
|
||||
PT_CONTINUE = 7 //Continue the process
|
||||
PT_KILL = 8 //Terminate the process
|
||||
PT_READ_GPR = 11 // Read GPR, CR, PSW
|
||||
PT_READ_FPR = 12 // Read FPR
|
||||
PT_READ_VR = 13 // Read VR
|
||||
PT_WRITE_GPR = 14 // Write GPR, CR, PSW
|
||||
PT_WRITE_FPR = 15 // Write FPR
|
||||
PT_WRITE_VR = 16 // Write VR
|
||||
PT_READ_BLOCK = 17 // Read storage
|
||||
PT_WRITE_BLOCK = 19 // Write storage
|
||||
PT_READ_GPRH = 20 // Read GPRH
|
||||
PT_WRITE_GPRH = 21 // Write GPRH
|
||||
PT_REGHSET = 22 // Read all GPRHs
|
||||
PT_ATTACH = 30 // Attach to a process
|
||||
PT_DETACH = 31 // Detach from a process
|
||||
PT_REGSET = 32 // Read all GPRs
|
||||
PT_REATTACH = 33 // Reattach to a process
|
||||
PT_LDINFO = 34 // Read loader info
|
||||
PT_MULTI = 35 // Multi process mode
|
||||
PT_LD64INFO = 36 // RMODE64 Info Area
|
||||
PT_BLOCKREQ = 40 // Block request
|
||||
PT_THREAD_INFO = 60 // Read thread info
|
||||
PT_THREAD_MODIFY = 61
|
||||
PT_THREAD_READ_FOCUS = 62
|
||||
PT_THREAD_WRITE_FOCUS = 63
|
||||
PT_THREAD_HOLD = 64
|
||||
PT_THREAD_SIGNAL = 65
|
||||
PT_EXPLAIN = 66
|
||||
PT_EVENTS = 67
|
||||
PT_THREAD_INFO_EXTENDED = 68
|
||||
PT_REATTACH2 = 71
|
||||
PT_CAPTURE = 72
|
||||
PT_UNCAPTURE = 73
|
||||
PT_GET_THREAD_TCB = 74
|
||||
PT_GET_ALET = 75
|
||||
PT_SWAPIN = 76
|
||||
PT_EXTENDED_EVENT = 98
|
||||
PT_RECOVER = 99 // Debug a program check
|
||||
PT_GPR0 = 0 // General purpose register 0
|
||||
PT_GPR1 = 1 // General purpose register 1
|
||||
PT_GPR2 = 2 // General purpose register 2
|
||||
PT_GPR3 = 3 // General purpose register 3
|
||||
PT_GPR4 = 4 // General purpose register 4
|
||||
PT_GPR5 = 5 // General purpose register 5
|
||||
PT_GPR6 = 6 // General purpose register 6
|
||||
PT_GPR7 = 7 // General purpose register 7
|
||||
PT_GPR8 = 8 // General purpose register 8
|
||||
PT_GPR9 = 9 // General purpose register 9
|
||||
PT_GPR10 = 10 // General purpose register 10
|
||||
PT_GPR11 = 11 // General purpose register 11
|
||||
PT_GPR12 = 12 // General purpose register 12
|
||||
PT_GPR13 = 13 // General purpose register 13
|
||||
PT_GPR14 = 14 // General purpose register 14
|
||||
PT_GPR15 = 15 // General purpose register 15
|
||||
PT_FPR0 = 16 // Floating point register 0
|
||||
PT_FPR1 = 17 // Floating point register 1
|
||||
PT_FPR2 = 18 // Floating point register 2
|
||||
PT_FPR3 = 19 // Floating point register 3
|
||||
PT_FPR4 = 20 // Floating point register 4
|
||||
PT_FPR5 = 21 // Floating point register 5
|
||||
PT_FPR6 = 22 // Floating point register 6
|
||||
PT_FPR7 = 23 // Floating point register 7
|
||||
PT_FPR8 = 24 // Floating point register 8
|
||||
PT_FPR9 = 25 // Floating point register 9
|
||||
PT_FPR10 = 26 // Floating point register 10
|
||||
PT_FPR11 = 27 // Floating point register 11
|
||||
PT_FPR12 = 28 // Floating point register 12
|
||||
PT_FPR13 = 29 // Floating point register 13
|
||||
PT_FPR14 = 30 // Floating point register 14
|
||||
PT_FPR15 = 31 // Floating point register 15
|
||||
PT_FPC = 32 // Floating point control register
|
||||
PT_PSW = 40 // PSW
|
||||
PT_PSW0 = 40 // Left half of the PSW
|
||||
PT_PSW1 = 41 // Right half of the PSW
|
||||
PT_CR0 = 42 // Control register 0
|
||||
PT_CR1 = 43 // Control register 1
|
||||
PT_CR2 = 44 // Control register 2
|
||||
PT_CR3 = 45 // Control register 3
|
||||
PT_CR4 = 46 // Control register 4
|
||||
PT_CR5 = 47 // Control register 5
|
||||
PT_CR6 = 48 // Control register 6
|
||||
PT_CR7 = 49 // Control register 7
|
||||
PT_CR8 = 50 // Control register 8
|
||||
PT_CR9 = 51 // Control register 9
|
||||
PT_CR10 = 52 // Control register 10
|
||||
PT_CR11 = 53 // Control register 11
|
||||
PT_CR12 = 54 // Control register 12
|
||||
PT_CR13 = 55 // Control register 13
|
||||
PT_CR14 = 56 // Control register 14
|
||||
PT_CR15 = 57 // Control register 15
|
||||
PT_GPRH0 = 58 // GP High register 0
|
||||
PT_GPRH1 = 59 // GP High register 1
|
||||
PT_GPRH2 = 60 // GP High register 2
|
||||
PT_GPRH3 = 61 // GP High register 3
|
||||
PT_GPRH4 = 62 // GP High register 4
|
||||
PT_GPRH5 = 63 // GP High register 5
|
||||
PT_GPRH6 = 64 // GP High register 6
|
||||
PT_GPRH7 = 65 // GP High register 7
|
||||
PT_GPRH8 = 66 // GP High register 8
|
||||
PT_GPRH9 = 67 // GP High register 9
|
||||
PT_GPRH10 = 68 // GP High register 10
|
||||
PT_GPRH11 = 69 // GP High register 11
|
||||
PT_GPRH12 = 70 // GP High register 12
|
||||
PT_GPRH13 = 71 // GP High register 13
|
||||
PT_GPRH14 = 72 // GP High register 14
|
||||
PT_GPRH15 = 73 // GP High register 15
|
||||
PT_VR0 = 74 // Vector register 0
|
||||
PT_VR1 = 75 // Vector register 1
|
||||
PT_VR2 = 76 // Vector register 2
|
||||
PT_VR3 = 77 // Vector register 3
|
||||
PT_VR4 = 78 // Vector register 4
|
||||
PT_VR5 = 79 // Vector register 5
|
||||
PT_VR6 = 80 // Vector register 6
|
||||
PT_VR7 = 81 // Vector register 7
|
||||
PT_VR8 = 82 // Vector register 8
|
||||
PT_VR9 = 83 // Vector register 9
|
||||
PT_VR10 = 84 // Vector register 10
|
||||
PT_VR11 = 85 // Vector register 11
|
||||
PT_VR12 = 86 // Vector register 12
|
||||
PT_VR13 = 87 // Vector register 13
|
||||
PT_VR14 = 88 // Vector register 14
|
||||
PT_VR15 = 89 // Vector register 15
|
||||
PT_VR16 = 90 // Vector register 16
|
||||
PT_VR17 = 91 // Vector register 17
|
||||
PT_VR18 = 92 // Vector register 18
|
||||
PT_VR19 = 93 // Vector register 19
|
||||
PT_VR20 = 94 // Vector register 20
|
||||
PT_VR21 = 95 // Vector register 21
|
||||
PT_VR22 = 96 // Vector register 22
|
||||
PT_VR23 = 97 // Vector register 23
|
||||
PT_VR24 = 98 // Vector register 24
|
||||
PT_VR25 = 99 // Vector register 25
|
||||
PT_VR26 = 100 // Vector register 26
|
||||
PT_VR27 = 101 // Vector register 27
|
||||
PT_VR28 = 102 // Vector register 28
|
||||
PT_VR29 = 103 // Vector register 29
|
||||
PT_VR30 = 104 // Vector register 30
|
||||
PT_VR31 = 105 // Vector register 31
|
||||
PT_PSWG = 106 // PSWG
|
||||
PT_PSWG0 = 106 // Bytes 0-3
|
||||
PT_PSWG1 = 107 // Bytes 4-7
|
||||
PT_PSWG2 = 108 // Bytes 8-11 (IA high word)
|
||||
PT_PSWG3 = 109 // Bytes 12-15 (IA low word)
|
||||
)
|
||||
|
||||
func Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {
|
||||
var parms [8]unsafe.Pointer
|
||||
parms[0] = unsafe.Pointer(&request)
|
||||
parms[1] = unsafe.Pointer(&pid)
|
||||
parms[2] = unsafe.Pointer(&addr)
|
||||
parms[3] = unsafe.Pointer(&data)
|
||||
parms[4] = unsafe.Pointer(&buffer)
|
||||
parms[5] = unsafe.Pointer(&rv)
|
||||
parms[6] = unsafe.Pointer(&rc)
|
||||
parms[7] = unsafe.Pointer(&rn)
|
||||
bpxcall(parms[:], BPX4PTR)
|
||||
return rv, rc, rn
|
||||
}
|
||||
|
||||
func copyU8(val uint8, dest []uint8) int {
|
||||
if len(dest) < 1 {
|
||||
return 0
|
||||
}
|
||||
dest[0] = val
|
||||
return 1
|
||||
}
|
||||
|
||||
func copyU8Arr(src, dest []uint8) int {
|
||||
if len(dest) < len(src) {
|
||||
return 0
|
||||
}
|
||||
for i, v := range src {
|
||||
dest[i] = v
|
||||
}
|
||||
return len(src)
|
||||
}
|
||||
|
||||
func copyU16(val uint16, dest []uint16) int {
|
||||
if len(dest) < 1 {
|
||||
return 0
|
||||
}
|
||||
dest[0] = val
|
||||
return 1
|
||||
}
|
||||
|
||||
func copyU32(val uint32, dest []uint32) int {
|
||||
if len(dest) < 1 {
|
||||
return 0
|
||||
}
|
||||
dest[0] = val
|
||||
return 1
|
||||
}
|
||||
|
||||
func copyU32Arr(src, dest []uint32) int {
|
||||
if len(dest) < len(src) {
|
||||
return 0
|
||||
}
|
||||
for i, v := range src {
|
||||
dest[i] = v
|
||||
}
|
||||
return len(src)
|
||||
}
|
||||
|
||||
func copyU64(val uint64, dest []uint64) int {
|
||||
if len(dest) < 1 {
|
||||
return 0
|
||||
}
|
||||
dest[0] = val
|
||||
return 1
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
// Copyright 2024 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 "go_asm.h"
|
||||
#include "textflag.h"
|
||||
|
||||
// function to call USS assembly language services
|
||||
//
|
||||
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bit64env.htm
|
||||
//
|
||||
// arg1 unsafe.Pointer array that ressembles an OS PLIST
|
||||
//
|
||||
// arg2 function offset as in
|
||||
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bpx2cr_List_of_offsets.htm
|
||||
//
|
||||
// func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
|
||||
|
||||
TEXT ·bpxcall(SB), NOSPLIT|NOFRAME, $0
|
||||
MOVD plist_base+0(FP), R1 // r1 points to plist
|
||||
MOVD bpx_offset+24(FP), R2 // r2 offset to BPX vector table
|
||||
MOVD R14, R7 // save r14
|
||||
MOVD R15, R8 // save r15
|
||||
MOVWZ 16(R0), R9
|
||||
MOVWZ 544(R9), R9
|
||||
MOVWZ 24(R9), R9 // call vector in r9
|
||||
ADD R2, R9 // add offset to vector table
|
||||
MOVWZ (R9), R9 // r9 points to entry point
|
||||
BYTE $0x0D // BL R14,R9 --> basr r14,r9
|
||||
BYTE $0xE9 // clobbers 0,1,14,15
|
||||
MOVD R8, R15 // restore 15
|
||||
JMP R7 // return via saved return address
|
||||
|
||||
// func A2e(arr [] byte)
|
||||
// code page conversion from 819 to 1047
|
||||
TEXT ·A2e(SB), NOSPLIT|NOFRAME, $0
|
||||
MOVD arg_base+0(FP), R2 // pointer to arry of characters
|
||||
MOVD arg_len+8(FP), R3 // count
|
||||
XOR R0, R0
|
||||
XOR R1, R1
|
||||
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
|
||||
|
||||
// ASCII -> EBCDIC conversion table:
|
||||
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
|
||||
BYTE $0x37; BYTE $0x2d; BYTE $0x2e; BYTE $0x2f
|
||||
BYTE $0x16; BYTE $0x05; BYTE $0x15; BYTE $0x0b
|
||||
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
|
||||
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
|
||||
BYTE $0x3c; BYTE $0x3d; BYTE $0x32; BYTE $0x26
|
||||
BYTE $0x18; BYTE $0x19; BYTE $0x3f; BYTE $0x27
|
||||
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
|
||||
BYTE $0x40; BYTE $0x5a; BYTE $0x7f; BYTE $0x7b
|
||||
BYTE $0x5b; BYTE $0x6c; BYTE $0x50; BYTE $0x7d
|
||||
BYTE $0x4d; BYTE $0x5d; BYTE $0x5c; BYTE $0x4e
|
||||
BYTE $0x6b; BYTE $0x60; BYTE $0x4b; BYTE $0x61
|
||||
BYTE $0xf0; BYTE $0xf1; BYTE $0xf2; BYTE $0xf3
|
||||
BYTE $0xf4; BYTE $0xf5; BYTE $0xf6; BYTE $0xf7
|
||||
BYTE $0xf8; BYTE $0xf9; BYTE $0x7a; BYTE $0x5e
|
||||
BYTE $0x4c; BYTE $0x7e; BYTE $0x6e; BYTE $0x6f
|
||||
BYTE $0x7c; BYTE $0xc1; BYTE $0xc2; BYTE $0xc3
|
||||
BYTE $0xc4; BYTE $0xc5; BYTE $0xc6; BYTE $0xc7
|
||||
BYTE $0xc8; BYTE $0xc9; BYTE $0xd1; BYTE $0xd2
|
||||
BYTE $0xd3; BYTE $0xd4; BYTE $0xd5; BYTE $0xd6
|
||||
BYTE $0xd7; BYTE $0xd8; BYTE $0xd9; BYTE $0xe2
|
||||
BYTE $0xe3; BYTE $0xe4; BYTE $0xe5; BYTE $0xe6
|
||||
BYTE $0xe7; BYTE $0xe8; BYTE $0xe9; BYTE $0xad
|
||||
BYTE $0xe0; BYTE $0xbd; BYTE $0x5f; BYTE $0x6d
|
||||
BYTE $0x79; BYTE $0x81; BYTE $0x82; BYTE $0x83
|
||||
BYTE $0x84; BYTE $0x85; BYTE $0x86; BYTE $0x87
|
||||
BYTE $0x88; BYTE $0x89; BYTE $0x91; BYTE $0x92
|
||||
BYTE $0x93; BYTE $0x94; BYTE $0x95; BYTE $0x96
|
||||
BYTE $0x97; BYTE $0x98; BYTE $0x99; BYTE $0xa2
|
||||
BYTE $0xa3; BYTE $0xa4; BYTE $0xa5; BYTE $0xa6
|
||||
BYTE $0xa7; BYTE $0xa8; BYTE $0xa9; BYTE $0xc0
|
||||
BYTE $0x4f; BYTE $0xd0; BYTE $0xa1; BYTE $0x07
|
||||
BYTE $0x20; BYTE $0x21; BYTE $0x22; BYTE $0x23
|
||||
BYTE $0x24; BYTE $0x25; BYTE $0x06; BYTE $0x17
|
||||
BYTE $0x28; BYTE $0x29; BYTE $0x2a; BYTE $0x2b
|
||||
BYTE $0x2c; BYTE $0x09; BYTE $0x0a; BYTE $0x1b
|
||||
BYTE $0x30; BYTE $0x31; BYTE $0x1a; BYTE $0x33
|
||||
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x08
|
||||
BYTE $0x38; BYTE $0x39; BYTE $0x3a; BYTE $0x3b
|
||||
BYTE $0x04; BYTE $0x14; BYTE $0x3e; BYTE $0xff
|
||||
BYTE $0x41; BYTE $0xaa; BYTE $0x4a; BYTE $0xb1
|
||||
BYTE $0x9f; BYTE $0xb2; BYTE $0x6a; BYTE $0xb5
|
||||
BYTE $0xbb; BYTE $0xb4; BYTE $0x9a; BYTE $0x8a
|
||||
BYTE $0xb0; BYTE $0xca; BYTE $0xaf; BYTE $0xbc
|
||||
BYTE $0x90; BYTE $0x8f; BYTE $0xea; BYTE $0xfa
|
||||
BYTE $0xbe; BYTE $0xa0; BYTE $0xb6; BYTE $0xb3
|
||||
BYTE $0x9d; BYTE $0xda; BYTE $0x9b; BYTE $0x8b
|
||||
BYTE $0xb7; BYTE $0xb8; BYTE $0xb9; BYTE $0xab
|
||||
BYTE $0x64; BYTE $0x65; BYTE $0x62; BYTE $0x66
|
||||
BYTE $0x63; BYTE $0x67; BYTE $0x9e; BYTE $0x68
|
||||
BYTE $0x74; BYTE $0x71; BYTE $0x72; BYTE $0x73
|
||||
BYTE $0x78; BYTE $0x75; BYTE $0x76; BYTE $0x77
|
||||
BYTE $0xac; BYTE $0x69; BYTE $0xed; BYTE $0xee
|
||||
BYTE $0xeb; BYTE $0xef; BYTE $0xec; BYTE $0xbf
|
||||
BYTE $0x80; BYTE $0xfd; BYTE $0xfe; BYTE $0xfb
|
||||
BYTE $0xfc; BYTE $0xba; BYTE $0xae; BYTE $0x59
|
||||
BYTE $0x44; BYTE $0x45; BYTE $0x42; BYTE $0x46
|
||||
BYTE $0x43; BYTE $0x47; BYTE $0x9c; BYTE $0x48
|
||||
BYTE $0x54; BYTE $0x51; BYTE $0x52; BYTE $0x53
|
||||
BYTE $0x58; BYTE $0x55; BYTE $0x56; BYTE $0x57
|
||||
BYTE $0x8c; BYTE $0x49; BYTE $0xcd; BYTE $0xce
|
||||
BYTE $0xcb; BYTE $0xcf; BYTE $0xcc; BYTE $0xe1
|
||||
BYTE $0x70; BYTE $0xdd; BYTE $0xde; BYTE $0xdb
|
||||
BYTE $0xdc; BYTE $0x8d; BYTE $0x8e; BYTE $0xdf
|
||||
|
||||
retry:
|
||||
WORD $0xB9931022 // TROO 2,2,b'0001'
|
||||
BVS retry
|
||||
RET
|
||||
|
||||
// func e2a(arr [] byte)
|
||||
// code page conversion from 1047 to 819
|
||||
TEXT ·E2a(SB), NOSPLIT|NOFRAME, $0
|
||||
MOVD arg_base+0(FP), R2 // pointer to arry of characters
|
||||
MOVD arg_len+8(FP), R3 // count
|
||||
XOR R0, R0
|
||||
XOR R1, R1
|
||||
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
|
||||
|
||||
// EBCDIC -> ASCII conversion table:
|
||||
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
|
||||
BYTE $0x9c; BYTE $0x09; BYTE $0x86; BYTE $0x7f
|
||||
BYTE $0x97; BYTE $0x8d; BYTE $0x8e; BYTE $0x0b
|
||||
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
|
||||
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
|
||||
BYTE $0x9d; BYTE $0x0a; BYTE $0x08; BYTE $0x87
|
||||
BYTE $0x18; BYTE $0x19; BYTE $0x92; BYTE $0x8f
|
||||
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
|
||||
BYTE $0x80; BYTE $0x81; BYTE $0x82; BYTE $0x83
|
||||
BYTE $0x84; BYTE $0x85; BYTE $0x17; BYTE $0x1b
|
||||
BYTE $0x88; BYTE $0x89; BYTE $0x8a; BYTE $0x8b
|
||||
BYTE $0x8c; BYTE $0x05; BYTE $0x06; BYTE $0x07
|
||||
BYTE $0x90; BYTE $0x91; BYTE $0x16; BYTE $0x93
|
||||
BYTE $0x94; BYTE $0x95; BYTE $0x96; BYTE $0x04
|
||||
BYTE $0x98; BYTE $0x99; BYTE $0x9a; BYTE $0x9b
|
||||
BYTE $0x14; BYTE $0x15; BYTE $0x9e; BYTE $0x1a
|
||||
BYTE $0x20; BYTE $0xa0; BYTE $0xe2; BYTE $0xe4
|
||||
BYTE $0xe0; BYTE $0xe1; BYTE $0xe3; BYTE $0xe5
|
||||
BYTE $0xe7; BYTE $0xf1; BYTE $0xa2; BYTE $0x2e
|
||||
BYTE $0x3c; BYTE $0x28; BYTE $0x2b; BYTE $0x7c
|
||||
BYTE $0x26; BYTE $0xe9; BYTE $0xea; BYTE $0xeb
|
||||
BYTE $0xe8; BYTE $0xed; BYTE $0xee; BYTE $0xef
|
||||
BYTE $0xec; BYTE $0xdf; BYTE $0x21; BYTE $0x24
|
||||
BYTE $0x2a; BYTE $0x29; BYTE $0x3b; BYTE $0x5e
|
||||
BYTE $0x2d; BYTE $0x2f; BYTE $0xc2; BYTE $0xc4
|
||||
BYTE $0xc0; BYTE $0xc1; BYTE $0xc3; BYTE $0xc5
|
||||
BYTE $0xc7; BYTE $0xd1; BYTE $0xa6; BYTE $0x2c
|
||||
BYTE $0x25; BYTE $0x5f; BYTE $0x3e; BYTE $0x3f
|
||||
BYTE $0xf8; BYTE $0xc9; BYTE $0xca; BYTE $0xcb
|
||||
BYTE $0xc8; BYTE $0xcd; BYTE $0xce; BYTE $0xcf
|
||||
BYTE $0xcc; BYTE $0x60; BYTE $0x3a; BYTE $0x23
|
||||
BYTE $0x40; BYTE $0x27; BYTE $0x3d; BYTE $0x22
|
||||
BYTE $0xd8; BYTE $0x61; BYTE $0x62; BYTE $0x63
|
||||
BYTE $0x64; BYTE $0x65; BYTE $0x66; BYTE $0x67
|
||||
BYTE $0x68; BYTE $0x69; BYTE $0xab; BYTE $0xbb
|
||||
BYTE $0xf0; BYTE $0xfd; BYTE $0xfe; BYTE $0xb1
|
||||
BYTE $0xb0; BYTE $0x6a; BYTE $0x6b; BYTE $0x6c
|
||||
BYTE $0x6d; BYTE $0x6e; BYTE $0x6f; BYTE $0x70
|
||||
BYTE $0x71; BYTE $0x72; BYTE $0xaa; BYTE $0xba
|
||||
BYTE $0xe6; BYTE $0xb8; BYTE $0xc6; BYTE $0xa4
|
||||
BYTE $0xb5; BYTE $0x7e; BYTE $0x73; BYTE $0x74
|
||||
BYTE $0x75; BYTE $0x76; BYTE $0x77; BYTE $0x78
|
||||
BYTE $0x79; BYTE $0x7a; BYTE $0xa1; BYTE $0xbf
|
||||
BYTE $0xd0; BYTE $0x5b; BYTE $0xde; BYTE $0xae
|
||||
BYTE $0xac; BYTE $0xa3; BYTE $0xa5; BYTE $0xb7
|
||||
BYTE $0xa9; BYTE $0xa7; BYTE $0xb6; BYTE $0xbc
|
||||
BYTE $0xbd; BYTE $0xbe; BYTE $0xdd; BYTE $0xa8
|
||||
BYTE $0xaf; BYTE $0x5d; BYTE $0xb4; BYTE $0xd7
|
||||
BYTE $0x7b; BYTE $0x41; BYTE $0x42; BYTE $0x43
|
||||
BYTE $0x44; BYTE $0x45; BYTE $0x46; BYTE $0x47
|
||||
BYTE $0x48; BYTE $0x49; BYTE $0xad; BYTE $0xf4
|
||||
BYTE $0xf6; BYTE $0xf2; BYTE $0xf3; BYTE $0xf5
|
||||
BYTE $0x7d; BYTE $0x4a; BYTE $0x4b; BYTE $0x4c
|
||||
BYTE $0x4d; BYTE $0x4e; BYTE $0x4f; BYTE $0x50
|
||||
BYTE $0x51; BYTE $0x52; BYTE $0xb9; BYTE $0xfb
|
||||
BYTE $0xfc; BYTE $0xf9; BYTE $0xfa; BYTE $0xff
|
||||
BYTE $0x5c; BYTE $0xf7; BYTE $0x53; BYTE $0x54
|
||||
BYTE $0x55; BYTE $0x56; BYTE $0x57; BYTE $0x58
|
||||
BYTE $0x59; BYTE $0x5a; BYTE $0xb2; BYTE $0xd4
|
||||
BYTE $0xd6; BYTE $0xd2; BYTE $0xd3; BYTE $0xd5
|
||||
BYTE $0x30; BYTE $0x31; BYTE $0x32; BYTE $0x33
|
||||
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x37
|
||||
BYTE $0x38; BYTE $0x39; BYTE $0xb3; BYTE $0xdb
|
||||
BYTE $0xdc; BYTE $0xd9; BYTE $0xda; BYTE $0x9f
|
||||
|
||||
retry:
|
||||
WORD $0xB9931022 // TROO 2,2,b'0001'
|
||||
BVS retry
|
||||
RET
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix && ppc
|
||||
// +build aix,ppc
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by AIX.
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix && ppc64
|
||||
// +build aix,ppc64
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used AIX.
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by z/OS.
|
||||
|
||||
+1
-2
@@ -2,8 +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 || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64
|
||||
// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
|
||||
// +build 386 amd64 amd64p32 alpha arm arm64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh
|
||||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh
|
||||
|
||||
package unix
|
||||
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||
|
||||
// Unix environment variables.
|
||||
|
||||
|
||||
-221
@@ -1,221 +0,0 @@
|
||||
// Copyright 2020 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 zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// This file simulates epoll on z/OS using poll.
|
||||
|
||||
// Analogous to epoll_event on Linux.
|
||||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
|
||||
type EpollEvent struct {
|
||||
Events uint32
|
||||
Fd int32
|
||||
Pad int32
|
||||
}
|
||||
|
||||
const (
|
||||
EPOLLERR = 0x8
|
||||
EPOLLHUP = 0x10
|
||||
EPOLLIN = 0x1
|
||||
EPOLLMSG = 0x400
|
||||
EPOLLOUT = 0x4
|
||||
EPOLLPRI = 0x2
|
||||
EPOLLRDBAND = 0x80
|
||||
EPOLLRDNORM = 0x40
|
||||
EPOLLWRBAND = 0x200
|
||||
EPOLLWRNORM = 0x100
|
||||
EPOLL_CTL_ADD = 0x1
|
||||
EPOLL_CTL_DEL = 0x2
|
||||
EPOLL_CTL_MOD = 0x3
|
||||
// The following constants are part of the epoll API, but represent
|
||||
// currently unsupported functionality on z/OS.
|
||||
// EPOLL_CLOEXEC = 0x80000
|
||||
// EPOLLET = 0x80000000
|
||||
// EPOLLONESHOT = 0x40000000
|
||||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
|
||||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
|
||||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
|
||||
)
|
||||
|
||||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
|
||||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
|
||||
|
||||
// epToPollEvt converts epoll event field to poll equivalent.
|
||||
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
|
||||
func epToPollEvt(events uint32) int16 {
|
||||
var ep2p = map[uint32]int16{
|
||||
EPOLLIN: POLLIN,
|
||||
EPOLLOUT: POLLOUT,
|
||||
EPOLLHUP: POLLHUP,
|
||||
EPOLLPRI: POLLPRI,
|
||||
EPOLLERR: POLLERR,
|
||||
}
|
||||
|
||||
var pollEvts int16 = 0
|
||||
for epEvt, pEvt := range ep2p {
|
||||
if (events & epEvt) != 0 {
|
||||
pollEvts |= pEvt
|
||||
}
|
||||
}
|
||||
|
||||
return pollEvts
|
||||
}
|
||||
|
||||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
|
||||
func pToEpollEvt(revents int16) uint32 {
|
||||
var p2ep = map[int16]uint32{
|
||||
POLLIN: EPOLLIN,
|
||||
POLLOUT: EPOLLOUT,
|
||||
POLLHUP: EPOLLHUP,
|
||||
POLLPRI: EPOLLPRI,
|
||||
POLLERR: EPOLLERR,
|
||||
}
|
||||
|
||||
var epollEvts uint32 = 0
|
||||
for pEvt, epEvt := range p2ep {
|
||||
if (revents & pEvt) != 0 {
|
||||
epollEvts |= epEvt
|
||||
}
|
||||
}
|
||||
|
||||
return epollEvts
|
||||
}
|
||||
|
||||
// Per-process epoll implementation.
|
||||
type epollImpl struct {
|
||||
mu sync.Mutex
|
||||
epfd2ep map[int]*eventPoll
|
||||
nextEpfd int
|
||||
}
|
||||
|
||||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
|
||||
// On Linux, this is an in-kernel data structure accessed through a fd.
|
||||
type eventPoll struct {
|
||||
mu sync.Mutex
|
||||
fds map[int]*EpollEvent
|
||||
}
|
||||
|
||||
// epoll impl for this process.
|
||||
var impl epollImpl = epollImpl{
|
||||
epfd2ep: make(map[int]*eventPoll),
|
||||
nextEpfd: 0,
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
epfd = e.nextEpfd
|
||||
e.nextEpfd++
|
||||
|
||||
e.epfd2ep[epfd] = &eventPoll{
|
||||
fds: make(map[int]*EpollEvent),
|
||||
}
|
||||
return epfd, nil
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
|
||||
return e.epollcreate(4)
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
ep, ok := e.epfd2ep[epfd]
|
||||
if !ok {
|
||||
|
||||
return EBADF
|
||||
}
|
||||
|
||||
switch op {
|
||||
case EPOLL_CTL_ADD:
|
||||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
|
||||
// loops here (instances watching each other) and return ELOOP.
|
||||
if _, ok := ep.fds[fd]; ok {
|
||||
return EEXIST
|
||||
}
|
||||
ep.fds[fd] = event
|
||||
case EPOLL_CTL_MOD:
|
||||
if _, ok := ep.fds[fd]; !ok {
|
||||
return ENOENT
|
||||
}
|
||||
ep.fds[fd] = event
|
||||
case EPOLL_CTL_DEL:
|
||||
if _, ok := ep.fds[fd]; !ok {
|
||||
return ENOENT
|
||||
}
|
||||
delete(ep.fds, fd)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Must be called while holding ep.mu
|
||||
func (ep *eventPoll) getFds() []int {
|
||||
fds := make([]int, len(ep.fds))
|
||||
for fd := range ep.fds {
|
||||
fds = append(fds, fd)
|
||||
}
|
||||
return fds
|
||||
}
|
||||
|
||||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
|
||||
ep, ok := e.epfd2ep[epfd]
|
||||
|
||||
if !ok {
|
||||
e.mu.Unlock()
|
||||
return 0, EBADF
|
||||
}
|
||||
|
||||
pollfds := make([]PollFd, 4)
|
||||
for fd, epollevt := range ep.fds {
|
||||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
|
||||
}
|
||||
e.mu.Unlock()
|
||||
|
||||
n, err = Poll(pollfds, msec)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
i := 0
|
||||
for _, pFd := range pollfds {
|
||||
if pFd.Revents != 0 {
|
||||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
|
||||
i++
|
||||
}
|
||||
|
||||
if i == n {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func EpollCreate(size int) (fd int, err error) {
|
||||
return impl.epollcreate(size)
|
||||
}
|
||||
|
||||
func EpollCreate1(flag int) (fd int, err error) {
|
||||
return impl.epollcreate1(flag)
|
||||
}
|
||||
|
||||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
||||
return impl.epollctl(epfd, op, fd, event)
|
||||
}
|
||||
|
||||
// Because EpollWait mutates events, the caller is expected to coordinate
|
||||
// concurrent access if calling with the same epfd from multiple goroutines.
|
||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||
return impl.epollwait(epfd, events, msec)
|
||||
}
|
||||
-233
@@ -1,233 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_IPXIP = 0xf9
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user