github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/sys/cpu/cpu_netbsd_arm64.go (about) 1 // Copyright 2020 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 5 package cpu 6 7 import ( 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 15 const ( 16 _CTL_QUERY = -2 17 18 _SYSCTL_VERS_1 = 0x1000000 19 ) 20 21 var _zero uintptr 22 23 func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { 24 var _p0 unsafe.Pointer 25 if len(mib) > 0 { 26 _p0 = unsafe.Pointer(&mib[0]) 27 } else { 28 _p0 = unsafe.Pointer(&_zero) 29 } 30 _, _, errno := syscall.Syscall6( 31 syscall.SYS___SYSCTL, 32 uintptr(_p0), 33 uintptr(len(mib)), 34 uintptr(unsafe.Pointer(old)), 35 uintptr(unsafe.Pointer(oldlen)), 36 uintptr(unsafe.Pointer(new)), 37 uintptr(newlen)) 38 if errno != 0 { 39 return errno 40 } 41 return nil 42 } 43 44 type sysctlNode struct { 45 Flags uint32 46 Num int32 47 Name [32]int8 48 Ver uint32 49 __rsvd uint32 50 Un [16]byte 51 _sysctl_size [8]byte 52 _sysctl_func [8]byte 53 _sysctl_parent [8]byte 54 _sysctl_desc [8]byte 55 } 56 57 func sysctlNodes(mib []int32) ([]sysctlNode, error) { 58 var olen uintptr 59 60 // Get a list of all sysctl nodes below the given MIB by performing 61 // a sysctl for the given MIB with CTL_QUERY appended. 62 mib = append(mib, _CTL_QUERY) 63 qnode := sysctlNode{Flags: _SYSCTL_VERS_1} 64 qp := (*byte)(unsafe.Pointer(&qnode)) 65 sz := unsafe.Sizeof(qnode) 66 if err := sysctl(mib, nil, &olen, qp, sz); err != nil { 67 return nil, err 68 } 69 70 // Now that we know the size, get the actual nodes. 71 nodes := make([]sysctlNode, olen/sz) 72 np := (*byte)(unsafe.Pointer(&nodes[0])) 73 if err := sysctl(mib, np, &olen, qp, sz); err != nil { 74 return nil, err 75 } 76 77 return nodes, nil 78 } 79 80 func nametomib(name string) ([]int32, error) { 81 // Split name into components. 82 var parts []string 83 last := 0 84 for i := 0; i < len(name); i++ { 85 if name[i] == '.' { 86 parts = append(parts, name[last:i]) 87 last = i + 1 88 } 89 } 90 parts = append(parts, name[last:]) 91 92 mib := []int32{} 93 // Discover the nodes and construct the MIB OID. 94 for partno, part := range parts { 95 nodes, err := sysctlNodes(mib) 96 if err != nil { 97 return nil, err 98 } 99 for _, node := range nodes { 100 n := make([]byte, 0) 101 for i := range node.Name { 102 if node.Name[i] != 0 { 103 n = append(n, byte(node.Name[i])) 104 } 105 } 106 if string(n) == part { 107 mib = append(mib, int32(node.Num)) 108 break 109 } 110 } 111 if len(mib) != partno+1 { 112 return nil, err 113 } 114 } 115 116 return mib, nil 117 } 118 119 // aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's <aarch64/armreg.h> 120 type aarch64SysctlCPUID struct { 121 midr uint64 /* Main ID Register */ 122 revidr uint64 /* Revision ID Register */ 123 mpidr uint64 /* Multiprocessor Affinity Register */ 124 aa64dfr0 uint64 /* A64 Debug Feature Register 0 */ 125 aa64dfr1 uint64 /* A64 Debug Feature Register 1 */ 126 aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */ 127 aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */ 128 aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */ 129 aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */ 130 aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */ 131 aa64pfr0 uint64 /* A64 Processor Feature Register 0 */ 132 aa64pfr1 uint64 /* A64 Processor Feature Register 1 */ 133 aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */ 134 mvfr0 uint32 /* Media and VFP Feature Register 0 */ 135 mvfr1 uint32 /* Media and VFP Feature Register 1 */ 136 mvfr2 uint32 /* Media and VFP Feature Register 2 */ 137 pad uint32 138 clidr uint64 /* Cache Level ID Register */ 139 ctr uint64 /* Cache Type Register */ 140 } 141 142 func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) { 143 mib, err := nametomib(name) 144 if err != nil { 145 return nil, err 146 } 147 148 out := aarch64SysctlCPUID{} 149 n := unsafe.Sizeof(out) 150 _, _, errno := syscall.Syscall6( 151 syscall.SYS___SYSCTL, 152 uintptr(unsafe.Pointer(&mib[0])), 153 uintptr(len(mib)), 154 uintptr(unsafe.Pointer(&out)), 155 uintptr(unsafe.Pointer(&n)), 156 uintptr(0), 157 uintptr(0)) 158 if errno != 0 { 159 return nil, errno 160 } 161 return &out, nil 162 } 163 164 func doinit() { 165 cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id") 166 if err != nil { 167 setMinimalFeatures() 168 return 169 } 170 parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) 171 172 Initialized = true 173 }