]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm64/sysctl.c
xnu-6153.61.1.tar.gz
[apple/xnu.git] / bsd / dev / arm64 / sysctl.c
1 /*
2 * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
3 */
4 #include <sys/param.h>
5 #include <sys/kernel.h>
6 #include <sys/sysctl.h>
7
8 #include <machine/machine_routines.h>
9
10 #include <mach/host_info.h>
11 #include <mach/mach_host.h>
12 #include <arm/cpuid.h>
13 #include <libkern/libkern.h>
14
15 extern uint64_t wake_abstime;
16 extern int lck_mtx_adaptive_spin_mode;
17
18 static
19 SYSCTL_QUAD(_machdep, OID_AUTO, wake_abstime,
20 CTLFLAG_RD, &wake_abstime,
21 "Absolute Time at the last wakeup");
22
23 static int
24 sysctl_time_since_reset SYSCTL_HANDLER_ARGS
25 {
26 #pragma unused(arg1, arg2, oidp)
27 uint64_t return_value = ml_get_time_since_reset();
28 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
29 }
30
31 SYSCTL_PROC(_machdep, OID_AUTO, time_since_reset,
32 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
33 0, 0, sysctl_time_since_reset, "I",
34 "Continuous time since last SOC boot/wake started");
35
36 static int
37 sysctl_wake_conttime SYSCTL_HANDLER_ARGS
38 {
39 #pragma unused(arg1, arg2, oidp)
40 uint64_t return_value = ml_get_conttime_wake_time();
41 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
42 }
43
44 SYSCTL_PROC(_machdep, OID_AUTO, wake_conttime,
45 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
46 0, 0, sysctl_wake_conttime, "I",
47 "Continuous Time at the last wakeup");
48
49
50 /*
51 * For source compatibility, here's some machdep.cpu mibs that
52 * use host_info() to simulate reasonable answers.
53 */
54
55 SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
56 "CPU info");
57
58 static int
59 arm_host_info SYSCTL_HANDLER_ARGS
60 {
61 __unused struct sysctl_oid *unused_oidp = oidp;
62
63 host_basic_info_data_t hinfo;
64 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
65 #define BSD_HOST 1
66 kern_return_t kret = host_info((host_t)BSD_HOST,
67 HOST_BASIC_INFO, (host_info_t)&hinfo, &count);
68 if (KERN_SUCCESS != kret) {
69 return EINVAL;
70 }
71
72 if (sizeof(uint32_t) != arg2) {
73 panic("size mismatch");
74 }
75
76 uintptr_t woffset = (uintptr_t)arg1 / sizeof(uint32_t);
77 uint32_t datum = *(uint32_t *)(((uint32_t *)&hinfo) + woffset);
78 return SYSCTL_OUT(req, &datum, sizeof(datum));
79 }
80
81 /*
82 * machdep.cpu.cores_per_package
83 *
84 * x86: derived from CPUID data.
85 * ARM: how many physical cores we have in the AP; aka hw.physicalcpu_max
86 */
87 static
88 SYSCTL_PROC(_machdep_cpu, OID_AUTO, cores_per_package,
89 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
90 (void *)offsetof(host_basic_info_data_t, physical_cpu_max),
91 sizeof(integer_t),
92 arm_host_info, "I", "CPU cores per package");
93
94 /*
95 * machdep.cpu.core_count
96 *
97 * x86: derived from CPUID data.
98 * ARM: # active physical cores in the AP; aka hw.physicalcpu
99 */
100 static
101 SYSCTL_PROC(_machdep_cpu, OID_AUTO, core_count,
102 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
103 (void *)offsetof(host_basic_info_data_t, physical_cpu),
104 sizeof(integer_t),
105 arm_host_info, "I", "Number of enabled cores per package");
106
107 /*
108 * machdep.cpu.logical_per_package
109 *
110 * x86: derived from CPUID data. Returns ENOENT if HTT bit not set, but
111 * most x64 CPUs have that, so assume it's available.
112 * ARM: total # logical cores in the AP; aka hw.logicalcpu_max
113 */
114 static
115 SYSCTL_PROC(_machdep_cpu, OID_AUTO, logical_per_package,
116 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
117 (void *)offsetof(host_basic_info_data_t, logical_cpu_max),
118 sizeof(integer_t),
119 arm_host_info, "I", "CPU logical cpus per package");
120
121 /*
122 * machdep.cpu.thread_count
123 *
124 * x86: derived from CPUID data.
125 * ARM: # active logical cores in the AP; aka hw.logicalcpu
126 */
127 static
128 SYSCTL_PROC(_machdep_cpu, OID_AUTO, thread_count,
129 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
130 (void *)offsetof(host_basic_info_data_t, logical_cpu),
131 sizeof(integer_t),
132 arm_host_info, "I", "Number of enabled threads per package");
133
134 /*
135 * machdep.cpu.brand_string
136 *
137 * x86: derived from CPUID data.
138 * ARM: cons something up from the CPUID register. Could include cpufamily
139 * here and map it to a "marketing" name, but there's no obvious need;
140 * the value is already exported via the commpage. So keep it simple.
141 */
142 static int
143 make_brand_string SYSCTL_HANDLER_ARGS
144 {
145 __unused struct sysctl_oid *unused_oidp = oidp;
146 __unused void *unused_arg1 = arg1;
147 __unused int unused_arg2 = arg2;
148
149 const char *impl;
150
151 switch (cpuid_info()->arm_info.arm_implementor) {
152 case CPU_VID_APPLE:
153 impl = "Apple";
154 break;
155 case CPU_VID_ARM:
156 impl = "ARM";
157 break;
158 default:
159 impl = "ARM architecture";
160 break;
161 }
162 char buf[80];
163 snprintf(buf, sizeof(buf), "%s processor", impl);
164 return SYSCTL_OUT(req, buf, strlen(buf) + 1);
165 }
166
167 SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand_string,
168 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
169 0, 0, make_brand_string, "A", "CPU brand string");
170
171 static
172 SYSCTL_INT(_machdep, OID_AUTO, lck_mtx_adaptive_spin_mode,
173 CTLFLAG_RW, &lck_mtx_adaptive_spin_mode, 0,
174 "Enable adaptive spin behavior for kernel mutexes");
175
176
177 #if DEVELOPMENT || DEBUG
178 extern uint64_t TLockTimeOut;
179 SYSCTL_QUAD(_machdep, OID_AUTO, tlto,
180 CTLFLAG_RW | CTLFLAG_LOCKED, &TLockTimeOut,
181 "Ticket spinlock timeout (MATUs): use with care");
182
183 static int
184 sysctl_sysreg_vbar_el1 SYSCTL_HANDLER_ARGS
185 {
186 #pragma unused(arg1, arg2, oidp)
187 uint64_t return_value = __builtin_arm_rsr64("VBAR_EL1");
188 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
189 }
190
191 /*
192 * machdep.cpu.sysreg_vbar_el1
193 *
194 * ARM64: Vector Base Address Register.
195 * Read from the current CPU's system registers.
196 */
197 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_vbar_el1,
198 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
199 0, 0, sysctl_sysreg_vbar_el1, "Q",
200 "VBAR_EL1 register on the current CPU");
201
202 static int
203 sysctl_sysreg_mair_el1 SYSCTL_HANDLER_ARGS
204 {
205 #pragma unused(arg1, arg2, oidp)
206 uint64_t return_value = __builtin_arm_rsr64("MAIR_EL1");
207 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
208 }
209
210 /*
211 * machdep.cpu.sysreg_mair_el1
212 *
213 * ARM64: Memory Attribute Indirection Register.
214 * Read from the current CPU's system registers.
215 */
216 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_mair_el1,
217 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
218 0, 0, sysctl_sysreg_mair_el1, "Q",
219 "MAIR_EL1 register on the current CPU");
220
221 static int
222 sysctl_sysreg_ttbr1_el1 SYSCTL_HANDLER_ARGS
223 {
224 #pragma unused(arg1, arg2, oidp)
225 uint64_t return_value = __builtin_arm_rsr64("TTBR1_EL1");
226 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
227 }
228
229 /*
230 * machdep.cpu.sysreg_ttbr1_el1
231 *
232 * ARM64: Translation table base register 1.
233 * Read from the current CPU's system registers.
234 */
235 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_ttbr1_el1,
236 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
237 0, 0, sysctl_sysreg_ttbr1_el1, "Q",
238 "TTBR1_EL1 register on the current CPU");
239
240 static int
241 sysctl_sysreg_sctlr_el1 SYSCTL_HANDLER_ARGS
242 {
243 #pragma unused(arg1, arg2, oidp)
244 uint64_t return_value = __builtin_arm_rsr64("SCTLR_EL1");
245 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
246 }
247
248 /*
249 * machdep.cpu.sysreg_sctlr_el1
250 *
251 * ARM64: System Control Register.
252 * Read from the current CPU's system registers.
253 */
254 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_sctlr_el1,
255 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
256 0, 0, sysctl_sysreg_sctlr_el1, "Q",
257 "SCTLR_EL1 register on the current CPU");
258
259 static int
260 sysctl_sysreg_tcr_el1 SYSCTL_HANDLER_ARGS
261 {
262 #pragma unused(arg1, arg2, oidp)
263 uint64_t return_value = __builtin_arm_rsr64("TCR_EL1");
264 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
265 }
266
267 /*
268 * machdep.cpu.sysreg_tcr_el1
269 *
270 * ARM64: Translation Control Register.
271 * Read from the current CPU's system registers.
272 */
273 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_tcr_el1,
274 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
275 0, 0, sysctl_sysreg_tcr_el1, "Q",
276 "TCR_EL1 register on the current CPU");
277
278 static int
279 sysctl_sysreg_id_aa64mmfr0_el1 SYSCTL_HANDLER_ARGS
280 {
281 #pragma unused(arg1, arg2, oidp)
282 uint64_t return_value = __builtin_arm_rsr64("ID_AA64MMFR0_EL1");
283 return SYSCTL_OUT(req, &return_value, sizeof(return_value));
284 }
285
286 /*
287 * machdep.cpu.sysreg_id_aa64mmfr0_el1
288 *
289 * ARM64: AArch64 Memory Model Feature Register 0.
290 * Read from the current CPU's system registers.
291 */
292 SYSCTL_PROC(_machdep_cpu, OID_AUTO, sysreg_id_aa64mmfr0_el1,
293 CTLFLAG_RD | CTLTYPE_QUAD | CTLFLAG_LOCKED,
294 0, 0, sysctl_sysreg_id_aa64mmfr0_el1, "Q",
295 "ID_AA64MMFR0_EL1 register on the current CPU");
296
297 #endif