From: Clément Chigot Date: Thu, 25 Oct 2018 09:23:53 +0000 (+0200) Subject: internal/cpu, runtime: add CPU feature detection support for AIX X-Git-Tag: go1.12beta1~564 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=cb07f492db5eae374901f94d8e55d8aeda1fca58;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Martin Möhrmann --- diff --git a/src/internal/cpu/cpu_ppc64x.go b/src/internal/cpu/cpu_ppc64x.go index 1e7959b306..880c4e1d01 100644 --- a/src/internal/cpu/cpu_ppc64x.go +++ b/src/internal/cpu/cpu_ppc64x.go @@ -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 { diff --git a/src/runtime/os2_aix.go b/src/runtime/os2_aix.go index 9e26ce23fc..c478d4b0d8 100644 --- a/src/runtime/os2_aix.go +++ b/src/runtime/os2_aix.go @@ -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)) diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go index 31590f22d8..141ce3bb11 100644 --- a/src/runtime/os_aix.go +++ b/src/runtime/os_aix.go @@ -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 + } +}