1
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
3
//go:build arm64 && !gccgo && !noasm && !appengine
4
// +build arm64,!gccgo,!noasm,!appengine
10
func getMidr() (midr uint64)
11
func getProcFeatures() (procFeatures uint64)
12
func getInstAttributes() (instAttrReg0, instAttrReg1 uint64)
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 }
21
func addInfo(c *CPUInfo, safe bool) {
22
// Seems to be safe to assume on ARM64
26
// ARM64 disabled since it may crash if interrupt is not intercepted by OS.
27
if safe && !c.Supports(ARMCPUID) && runtime.GOOS != "freebsd" {
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
48
switch (midr >> 24) & 0xff {
50
c.VendorString = "Ampere Computing"
53
c.VendorString = "Arm Limited"
56
c.VendorString = "Broadcom Corporation"
59
c.VendorString = "Cavium Inc"
62
c.VendorString = "Digital Equipment Corporation"
65
c.VendorString = "Fujitsu Ltd"
68
c.VendorString = "Infineon Technologies AG"
71
c.VendorString = "Motorola or Freescale Semiconductor Inc"
74
c.VendorString = "NVIDIA Corporation"
77
c.VendorString = "Applied Micro Circuits Corporation"
80
c.VendorString = "Qualcomm Inc"
83
c.VendorString = "Marvell International Ltd"
86
c.VendorString = "Intel Corporation"
90
// Lower 4 bits: Architecture
91
// Architecture Meaning
94
// 0b0011 Armv5 (obsolete).
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
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
113
procFeatures := getProcFeatures()
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
139
// if procFeatures&(0xf<<48) != 0 {
140
// fmt.Println("DIT")
142
f.setIf(procFeatures&(0xf<<32) != 0, SVE)
143
if procFeatures&(0xf<<20) != 15<<20 {
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)
149
f.setIf(procFeatures&(0xf<<16) != 0, FP)
151
instAttrReg0, instAttrReg1 := getInstAttributes()
153
// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
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
184
// if instAttrReg0&(0xf<<52) != 0 {
187
// if instAttrReg0&(0xf<<48) != 0 {
188
// fmt.Println("FHM")
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)
207
// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar1_el1
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
230
// if instAttrReg1&(0xf<<28) != 0 {
231
// fmt.Println("GPI")
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")
240
// if instAttrReg1&(0xf<<4) != 0 {
241
// fmt.Println("APA")
243
f.setIf(instAttrReg1&(0xf<<0) != 0, DCPOP)