cpu_openbsd_arm64.go

 1// Copyright 2022 The Go Authors. All rights reserved.
 2// Use of this source code is governed by a BSD-style
 3// license that can be found in the LICENSE file.
 4
 5package cpu
 6
 7import (
 8	"syscall"
 9	"unsafe"
10)
11
12// Minimal copy of functionality from x/sys/unix so the cpu package can call
13// sysctl without depending on x/sys/unix.
14
15const (
16	// From OpenBSD's sys/sysctl.h.
17	_CTL_MACHDEP = 7
18
19	// From OpenBSD's machine/cpu.h.
20	_CPU_ID_AA64ISAR0 = 2
21	_CPU_ID_AA64ISAR1 = 3
22)
23
24// Implemented in the runtime package (runtime/sys_openbsd3.go)
25func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
26
27//go:linkname syscall_syscall6 syscall.syscall6
28
29func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
30	_, _, 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))
31	if errno != 0 {
32		return errno
33	}
34	return nil
35}
36
37var libc_sysctl_trampoline_addr uintptr
38
39//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
40
41func sysctlUint64(mib []uint32) (uint64, bool) {
42	var out uint64
43	nout := unsafe.Sizeof(out)
44	if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
45		return 0, false
46	}
47	return out, true
48}
49
50func doinit() {
51	setMinimalFeatures()
52
53	// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
54	isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
55	if !ok {
56		return
57	}
58	isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
59	if !ok {
60		return
61	}
62	parseARM64SystemRegisters(isar0, isar1, 0)
63
64	Initialized = true
65}