1// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
2
3//+build arm64,!gccgo,!noasm,!appengine
4
5package cpuid
6
7func getMidr() (midr uint64)
8func getProcFeatures() (procFeatures uint64)
9func getInstAttributes() (instAttrReg0, instAttrReg1 uint64)
10
11func initCPU() {
12	cpuid = func(uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 }
13	cpuidex = func(x, y uint32) (a, b, c, d uint32) { return 0, 0, 0, 0 }
14	xgetbv = func(uint32) (a, b uint32) { return 0, 0 }
15	rdtscpAsm = func() (a, b, c, d uint32) { return 0, 0, 0, 0 }
16}
17
18func addInfo(c *CPUInfo) {
19	// ARM64 disabled for now.
20	if true {
21		return
22	}
23	// 	midr := getMidr()
24
25	// MIDR_EL1 - Main ID Register
26	//  x--------------------------------------------------x
27	//  | Name                         |  bits   | visible |
28	//  |--------------------------------------------------|
29	//  | Implementer                  | [31-24] |    y    |
30	//  |--------------------------------------------------|
31	//  | Variant                      | [23-20] |    y    |
32	//  |--------------------------------------------------|
33	//  | Architecture                 | [19-16] |    y    |
34	//  |--------------------------------------------------|
35	//  | PartNum                      | [15-4]  |    y    |
36	//  |--------------------------------------------------|
37	//  | Revision                     | [3-0]   |    y    |
38	//  x--------------------------------------------------x
39
40	// 	fmt.Printf(" implementer:  0x%02x\n", (midr>>24)&0xff)
41	// 	fmt.Printf("     variant:   0x%01x\n", (midr>>20)&0xf)
42	// 	fmt.Printf("architecture:   0x%01x\n", (midr>>16)&0xf)
43	// 	fmt.Printf("    part num: 0x%03x\n", (midr>>4)&0xfff)
44	// 	fmt.Printf("    revision:   0x%01x\n", (midr>>0)&0xf)
45
46	procFeatures := getProcFeatures()
47
48	// ID_AA64PFR0_EL1 - Processor Feature Register 0
49	// x--------------------------------------------------x
50	// | Name                         |  bits   | visible |
51	// |--------------------------------------------------|
52	// | DIT                          | [51-48] |    y    |
53	// |--------------------------------------------------|
54	// | SVE                          | [35-32] |    y    |
55	// |--------------------------------------------------|
56	// | GIC                          | [27-24] |    n    |
57	// |--------------------------------------------------|
58	// | AdvSIMD                      | [23-20] |    y    |
59	// |--------------------------------------------------|
60	// | FP                           | [19-16] |    y    |
61	// |--------------------------------------------------|
62	// | EL3                          | [15-12] |    n    |
63	// |--------------------------------------------------|
64	// | EL2                          | [11-8]  |    n    |
65	// |--------------------------------------------------|
66	// | EL1                          | [7-4]   |    n    |
67	// |--------------------------------------------------|
68	// | EL0                          | [3-0]   |    n    |
69	// x--------------------------------------------------x
70
71	var f ArmFlags
72	// if procFeatures&(0xf<<48) != 0 {
73	// 	fmt.Println("DIT")
74	// }
75	if procFeatures&(0xf<<32) != 0 {
76		f |= SVE
77	}
78	if procFeatures&(0xf<<20) != 15<<20 {
79		f |= ASIMD
80		if procFeatures&(0xf<<20) == 1<<20 {
81			// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64pfr0_el1
82			// 0b0001 --> As for 0b0000, and also includes support for half-precision floating-point arithmetic.
83			f |= FPHP
84			f |= ASIMDHP
85		}
86	}
87	if procFeatures&(0xf<<16) != 0 {
88		f |= FP
89	}
90
91	instAttrReg0, instAttrReg1 := getInstAttributes()
92
93	// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
94	//
95	// ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
96	// x--------------------------------------------------x
97	// | Name                         |  bits   | visible |
98	// |--------------------------------------------------|
99	// | TS                           | [55-52] |    y    |
100	// |--------------------------------------------------|
101	// | FHM                          | [51-48] |    y    |
102	// |--------------------------------------------------|
103	// | DP                           | [47-44] |    y    |
104	// |--------------------------------------------------|
105	// | SM4                          | [43-40] |    y    |
106	// |--------------------------------------------------|
107	// | SM3                          | [39-36] |    y    |
108	// |--------------------------------------------------|
109	// | SHA3                         | [35-32] |    y    |
110	// |--------------------------------------------------|
111	// | RDM                          | [31-28] |    y    |
112	// |--------------------------------------------------|
113	// | ATOMICS                      | [23-20] |    y    |
114	// |--------------------------------------------------|
115	// | CRC32                        | [19-16] |    y    |
116	// |--------------------------------------------------|
117	// | SHA2                         | [15-12] |    y    |
118	// |--------------------------------------------------|
119	// | SHA1                         | [11-8]  |    y    |
120	// |--------------------------------------------------|
121	// | AES                          | [7-4]   |    y    |
122	// x--------------------------------------------------x
123
124	// if instAttrReg0&(0xf<<52) != 0 {
125	// 	fmt.Println("TS")
126	// }
127	// if instAttrReg0&(0xf<<48) != 0 {
128	// 	fmt.Println("FHM")
129	// }
130	if instAttrReg0&(0xf<<44) != 0 {
131		f |= ASIMDDP
132	}
133	if instAttrReg0&(0xf<<40) != 0 {
134		f |= SM4
135	}
136	if instAttrReg0&(0xf<<36) != 0 {
137		f |= SM3
138	}
139	if instAttrReg0&(0xf<<32) != 0 {
140		f |= SHA3
141	}
142	if instAttrReg0&(0xf<<28) != 0 {
143		f |= ASIMDRDM
144	}
145	if instAttrReg0&(0xf<<20) != 0 {
146		f |= ATOMICS
147	}
148	if instAttrReg0&(0xf<<16) != 0 {
149		f |= CRC32
150	}
151	if instAttrReg0&(0xf<<12) != 0 {
152		f |= SHA2
153	}
154	if instAttrReg0&(0xf<<12) == 2<<12 {
155		// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
156		// 0b0010 --> As 0b0001, plus SHA512H, SHA512H2, SHA512SU0, and SHA512SU1 instructions implemented.
157		f |= SHA512
158	}
159	if instAttrReg0&(0xf<<8) != 0 {
160		f |= SHA1
161	}
162	if instAttrReg0&(0xf<<4) != 0 {
163		f |= AES
164	}
165	if instAttrReg0&(0xf<<4) == 2<<4 {
166		// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar0_el1
167		// 0b0010 --> As for 0b0001, plus PMULL/PMULL2 instructions operating on 64-bit data quantities.
168		f |= PMULL
169	}
170
171	// https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/id_aa64isar1_el1
172	//
173	// ID_AA64ISAR1_EL1 - Instruction set attribute register 1
174	// x--------------------------------------------------x
175	// | Name                         |  bits   | visible |
176	// |--------------------------------------------------|
177	// | GPI                          | [31-28] |    y    |
178	// |--------------------------------------------------|
179	// | GPA                          | [27-24] |    y    |
180	// |--------------------------------------------------|
181	// | LRCPC                        | [23-20] |    y    |
182	// |--------------------------------------------------|
183	// | FCMA                         | [19-16] |    y    |
184	// |--------------------------------------------------|
185	// | JSCVT                        | [15-12] |    y    |
186	// |--------------------------------------------------|
187	// | API                          | [11-8]  |    y    |
188	// |--------------------------------------------------|
189	// | APA                          | [7-4]   |    y    |
190	// |--------------------------------------------------|
191	// | DPB                          | [3-0]   |    y    |
192	// x--------------------------------------------------x
193
194	// if instAttrReg1&(0xf<<28) != 0 {
195	// 	fmt.Println("GPI")
196	// }
197	if instAttrReg1&(0xf<<28) != 24 {
198		f |= GPA
199	}
200	if instAttrReg1&(0xf<<20) != 0 {
201		f |= LRCPC
202	}
203	if instAttrReg1&(0xf<<16) != 0 {
204		f |= FCMA
205	}
206	if instAttrReg1&(0xf<<12) != 0 {
207		f |= JSCVT
208	}
209	// if instAttrReg1&(0xf<<8) != 0 {
210	// 	fmt.Println("API")
211	// }
212	// if instAttrReg1&(0xf<<4) != 0 {
213	// 	fmt.Println("APA")
214	// }
215	if instAttrReg1&(0xf<<0) != 0 {
216		f |= DCPOP
217	}
218	c.Arm = f
219}
220