aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/klauspost/cpuid/v2/detect_arm64.go')
-rw-r--r--vendor/github.com/klauspost/cpuid/v2/detect_arm64.go247
1 files changed, 247 insertions, 0 deletions
diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go b/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go
new file mode 100644
index 0000000..9a53504
--- /dev/null
+++ b/vendor/github.com/klauspost/cpuid/v2/detect_arm64.go
@@ -0,0 +1,247 @@
1// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
2
3//go:build arm64 && !gccgo && !noasm && !appengine
4// +build arm64,!gccgo,!noasm,!appengine
5
6package cpuid
7
8import "runtime"
9
10func getMidr() (midr uint64)
11func getProcFeatures() (procFeatures uint64)
12func getInstAttributes() (instAttrReg0, instAttrReg1 uint64)
13
14func initCPU() {
15 cpuid = func(uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 }
16 cpuidex = func(x, y uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 }
17 xgetbv = func(uint32) (a, b uint32) { return 0, 0 }
18 rdtscpAsm = func() (a, b, c, d uint32) { return 0, 0, 0, 0 }
19}
20
21func addInfo(c *CPUInfo, safe bool) {
22 // Seems to be safe to assume on ARM64
23 c.CacheLine = 64
24 detectOS(c)
25
26 // ARM64 disabled since it may crash if interrupt is not intercepted by OS.
27 if safe && !c.Supports(ARMCPUID) && runtime.GOOS != "freebsd" {
28 return
29 }
30 midr := getMidr()
31
32 // MIDR_EL1 - Main ID Register
33 // https://developer.arm.com/docs/ddi0595/h/aarch64-system-registers/midr_el1
34 // x--------------------------------------------------x
35 // | Name | bits | visible |
36 // |--------------------------------------------------|
37 // | Implementer | [31-24] | y |
38 // |--------------------------------------------------|
39 // | Variant | [23-20] | y |
40 // |--------------------------------------------------|
41 // | Architecture | [19-16] | y |
42 // |--------------------------------------------------|
43 // | PartNum | [15-4] | y |
44 // |--------------------------------------------------|
45 // | Revision | [3-0] | y |
46 // x--------------------------------------------------x
47
48 switch (midr >> 24) & 0xff {
49 case 0xC0:
50 c.VendorString = "Ampere Computing"
51 c.VendorID = Ampere
52 case 0x41:
53 c.VendorString = "Arm Limited"
54 c.VendorID = ARM
55 case 0x42:
56 c.VendorString = "Broadcom Corporation"
57 c.VendorID = Broadcom
58 case 0x43:
59 c.VendorString = "Cavium Inc"
60 c.VendorID = Cavium
61 case 0x44:
62 c.VendorString = "Digital Equipment Corporation"
63 c.VendorID = DEC
64 case 0x46:
65 c.VendorString = "Fujitsu Ltd"
66 c.VendorID = Fujitsu
67 case 0x49:
68 c.VendorString = "Infineon Technologies AG"
69 c.VendorID = Infineon
70 case 0x4D:
71 c.VendorString = "Motorola or Freescale Semiconductor Inc"
72 c.VendorID = Motorola
73 case 0x4E:
74 c.VendorString = "NVIDIA Corporation"
75 c.VendorID = NVIDIA
76 case 0x50:
77 c.VendorString = "Applied Micro Circuits Corporation"
78 c.VendorID = AMCC
79 case 0x51:
80 c.VendorString = "Qualcomm Inc"
81 c.VendorID = Qualcomm
82 case 0x56:
83 c.VendorString = "Marvell International Ltd"
84 c.VendorID = Marvell
85 case 0x69:
86 c.VendorString = "Intel Corporation"
87 c.VendorID = Intel
88 }
89
90 // Lower 4 bits: Architecture
91 // Architecture Meaning
92 // 0b0001 Armv4.
93 // 0b0010 Armv4T.
94 // 0b0011 Armv5 (obsolete).
95 // 0b0100 Armv5T.
96 // 0b0101 Armv5TE.
97 // 0b0110 Armv5TEJ.
98 // 0b0111 Armv6.
99 // 0b1111 Architectural features are individually identified in the ID_* registers, see 'ID registers'.
100 // Upper 4 bit: Variant
101 // An IMPLEMENTATION DEFINED variant number.
102 // Typically, this field is used to distinguish between different product variants, or major revisions of a product.
103 c.Family = int(midr>>16) & 0xff
104
105 // PartNum, bits [15:4]
106 // An IMPLEMENTATION DEFINED primary part number for the device.
107 // On processors implemented by Arm, if the top four bits of the primary
108 // part number are 0x0 or 0x7, the variant and architecture are encoded differently.
109 // Revision, bits [3:0]
110 // An IMPLEMENTATION DEFINED revision number for the device.
111 c.Model = int(midr) & 0xffff
112
113 procFeatures := getProcFeatures()
114
115 // ID_AA64PFR0_EL1 - Processor Feature Register 0
116 // x--------------------------------------------------x
117 // | Name | bits | visible |
118 // |--------------------------------------------------|
119 // | DIT | [51-48] | y |
120 // |--------------------------------------------------|
121 // | SVE | [35-32] | y |
122 // |--------------------------------------------------|
123 // | GIC | [27-24] | n |
124 // |--------------------------------------------------|
125 // | AdvSIMD | [23-20] | y |
126 // |--------------------------------------------------|
127 // | FP | [19-16] | y |
128 // |--------------------------------------------------|
129 // | EL3 | [15-12] | n |
130 // |--------------------------------------------------|
131 // | EL2 | [11-8] | n |
132 // |--------------------------------------------------|
133 // | EL1 | [7-4] | n |
134 // |--------------------------------------------------|
135 // | EL0 | [3-0] | n |
136 // x--------------------------------------------------x
137
138 var f flagSet
139 // if procFeatures&(0xf<<48) != 0 {
140 // fmt.Println("DIT")
141 // }
142 f.setIf(procFeatures&(0xf<<32) != 0, SVE)
143 if procFeatures&(0xf<<20) != 15<<20 {
144 f.set(ASIMD)
145 // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64pfr0_el1
146 // 0b0001 --> As for 0b0000, and also includes support for half-precision floating-point arithmetic.
147 f.setIf(procFeatures&(0xf<<20) == 1<<20, FPHP, ASIMDHP)
148 }
149 f.setIf(procFeatures&(0xf<<16) != 0, FP)
150
151 instAttrReg0, instAttrReg1 := getInstAttributes()
152
153 // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
154 //
155 // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
156 // x--------------------------------------------------x
157 // | Name | bits | visible |
158 // |--------------------------------------------------|
159 // | TS | [55-52] | y |
160 // |--------------------------------------------------|
161 // | FHM | [51-48] | y |
162 // |--------------------------------------------------|
163 // | DP | [47-44] | y |
164 // |--------------------------------------------------|
165 // | SM4 | [43-40] | y |
166 // |--------------------------------------------------|
167 // | SM3 | [39-36] | y |
168 // |--------------------------------------------------|
169 // | SHA3 | [35-32] | y |
170 // |--------------------------------------------------|
171 // | RDM | [31-28] | y |
172 // |--------------------------------------------------|
173 // | ATOMICS | [23-20] | y |
174 // |--------------------------------------------------|
175 // | CRC32 | [19-16] | y |
176 // |--------------------------------------------------|
177 // | SHA2 | [15-12] | y |
178 // |--------------------------------------------------|
179 // | SHA1 | [11-8] | y |
180 // |--------------------------------------------------|
181 // | AES | [7-4] | y |
182 // x--------------------------------------------------x
183
184 // if instAttrReg0&(0xf<<52) != 0 {
185 // fmt.Println("TS")
186 // }
187 // if instAttrReg0&(0xf<<48) != 0 {
188 // fmt.Println("FHM")
189 // }
190 f.setIf(instAttrReg0&(0xf<<44) != 0, ASIMDDP)
191 f.setIf(instAttrReg0&(0xf<<40) != 0, SM4)
192 f.setIf(instAttrReg0&(0xf<<36) != 0, SM3)
193 f.setIf(instAttrReg0&(0xf<<32) != 0, SHA3)
194 f.setIf(instAttrReg0&(0xf<<28) != 0, ASIMDRDM)
195 f.setIf(instAttrReg0&(0xf<<20) != 0, ATOMICS)
196 f.setIf(instAttrReg0&(0xf<<16) != 0, CRC32)
197 f.setIf(instAttrReg0&(0xf<<12) != 0, SHA2)
198 // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
199 // 0b0010 --> As 0b0001, plus SHA512H, SHA512H2, SHA512SU0, and SHA512SU1 instructions implemented.
200 f.setIf(instAttrReg0&(0xf<<12) == 2<<12, SHA512)
201 f.setIf(instAttrReg0&(0xf<<8) != 0, SHA1)
202 f.setIf(instAttrReg0&(0xf<<4) != 0, AESARM)
203 // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
204 // 0b0010 --> As for 0b0001, plus PMULL/PMULL2 instructions operating on 64-bit data quantities.
205 f.setIf(instAttrReg0&(0xf<<4) == 2<<4, PMULL)
206
207 // https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar1_el1
208 //
209 // ID_AA64ISAR1_EL1 - Instruction set attribute register 1
210 // x--------------------------------------------------x
211 // | Name | bits | visible |
212 // |--------------------------------------------------|
213 // | GPI | [31-28] | y |
214 // |--------------------------------------------------|
215 // | GPA | [27-24] | y |
216 // |--------------------------------------------------|
217 // | LRCPC | [23-20] | y |
218 // |--------------------------------------------------|
219 // | FCMA | [19-16] | y |
220 // |--------------------------------------------------|
221 // | JSCVT | [15-12] | y |
222 // |--------------------------------------------------|
223 // | API | [11-8] | y |
224 // |--------------------------------------------------|
225 // | APA | [7-4] | y |
226 // |--------------------------------------------------|
227 // | DPB | [3-0] | y |
228 // x--------------------------------------------------x
229
230 // if instAttrReg1&(0xf<<28) != 0 {
231 // fmt.Println("GPI")
232 // }
233 f.setIf(instAttrReg1&(0xf<<28) != 24, GPA)
234 f.setIf(instAttrReg1&(0xf<<20) != 0, LRCPC)
235 f.setIf(instAttrReg1&(0xf<<16) != 0, FCMA)
236 f.setIf(instAttrReg1&(0xf<<12) != 0, JSCVT)
237 // if instAttrReg1&(0xf<<8) != 0 {
238 // fmt.Println("API")
239 // }
240 // if instAttrReg1&(0xf<<4) != 0 {
241 // fmt.Println("APA")
242 // }
243 f.setIf(instAttrReg1&(0xf<<0) != 0, DCPOP)
244
245 // Store
246 c.featureSet.or(f)
247}