Commit cb07f492 authored by Clément Chigot's avatar Clément Chigot Committed by Martin Möhrmann

internal/cpu, runtime: add CPU feature detection support for AIX

AIX doesn't have HWCAP/HWCAP2 variables like Linux. Therefore, it relies on
getsystemcfg syscall which can provide some information about the CPU.

Change-Id: Ic0dc927e80890d4bf8f0bdfb43fad1e2b890d7a0
Reviewed-on: https://go-review.googlesource.com/c/144959
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMartin Möhrmann <moehrmann@google.com>
parent 53856c47
......@@ -11,18 +11,19 @@ const CacheLinePadSize = 128
// ppc64x doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2.
// These are initialized by archauxv in runtime/os_linux_ppc64x.go.
// These should not be changed after they are initialized.
// On aix/ppc64, these values are initialized early in the runtime in runtime/os_aix.go.
var HWCap uint
var HWCap2 uint
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
const (
// ISA Level
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
PPC_FEATURE2_ARCH_2_07 = 0x80000000
PPC_FEATURE2_ARCH_3_00 = 0x00800000
// CPU features
_PPC_FEATURE2_DARN = 0x00200000
_PPC_FEATURE2_SCV = 0x00100000
PPC_FEATURE2_DARN = 0x00200000
PPC_FEATURE2_SCV = 0x00100000
)
func doinit() {
......@@ -36,10 +37,10 @@ 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)
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 {
......
......@@ -33,6 +33,7 @@ var (
//go:cgo_import_dynamic libc_close close "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_exit exit "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_kill kill "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_malloc malloc "libc.a/shr_64.o"
......@@ -69,6 +70,7 @@ var (
//go:linkname libc_close libc_close
//go:linkname libc_exit libc_exit
//go:linkname libc_getpid libc_getpid
//go:linkname libc_getsystemcfg libc_getsystemcfg
//go:linkname libc_kill libc_kill
//go:linkname libc_madvise libc_madvise
//go:linkname libc_malloc libc_malloc
......@@ -107,6 +109,7 @@ var (
libc_close,
libc_exit,
libc_getpid,
libc_getsystemcfg,
libc_kill,
libc_madvise,
libc_malloc,
......@@ -319,6 +322,12 @@ func sigaltstack(new, old *stackt) {
}
}
//go:nosplit
func getsystemcfg(label uint) uintptr {
r, _ := syscall1(&libc_getsystemcfg, uintptr(label))
return r
}
//go:nosplit
func usleep(us uint32) {
r, err := syscall1(&libc_usleep, uintptr(us))
......
......@@ -7,6 +7,7 @@
package runtime
import (
"internal/cpu"
"unsafe"
)
......@@ -93,6 +94,7 @@ func semawakeup(mp *m) {
func osinit() {
ncpu = int32(sysconf(__SC_NPROCESSORS_ONLN))
physPageSize = sysconf(__SC_PAGE_SIZE)
setupSystemConf()
}
// Ms related functions
......@@ -260,3 +262,22 @@ func walltime() (sec int64, nsec int32) {
}
return ts.tv_sec, int32(ts.tv_nsec)
}
const (
// getsystemcfg constants
_SC_IMPL = 2
_IMPL_POWER8 = 0x10000
_IMPL_POWER9 = 0x20000
)
// setupSystemConf retrieves information about the CPU and updates
// cpu.HWCap variables.
func setupSystemConf() {
impl := getsystemcfg(_SC_IMPL)
if impl&_IMPL_POWER8 != 0 {
cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_2_07
}
if impl&_IMPL_POWER9 != 0 {
cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_3_00
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment