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