2 * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
5 #include <sys/kernel.h>
6 #include <sys/sysctl.h>
8 #include <machine/machine_routines.h>
10 #include <mach/host_info.h>
11 #include <mach/mach_host.h>
12 #include <arm/cpuid.h>
13 #include <libkern/libkern.h>
15 extern uint64_t wake_abstime
;
16 extern int lck_mtx_adaptive_spin_mode
;
19 SYSCTL_QUAD(_machdep
, OID_AUTO
, wake_abstime
,
20 CTLFLAG_RD
, &wake_abstime
,
21 "Absolute Time at the last wakeup");
24 sysctl_time_since_reset SYSCTL_HANDLER_ARGS
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
));
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");
37 sysctl_wake_conttime SYSCTL_HANDLER_ARGS
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
));
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");
51 cpu_signal_deferred_timer(__unused
struct sysctl_oid
*oidp
, __unused
void *arg1
, __unused
int arg2
, struct sysctl_req
*req
)
56 int old_value
= (int)ml_cpu_signal_deferred_get_timer();
58 int error
= sysctl_io_number(req
, old_value
, sizeof(int), &new_value
, &changed
);
60 if (error
== 0 && changed
) {
61 ml_cpu_signal_deferred_adjust_timer((uint64_t)new_value
);
67 SYSCTL_PROC(_machdep
, OID_AUTO
, deferred_ipi_timeout
,
68 CTLTYPE_INT
| CTLFLAG_RW
| CTLFLAG_LOCKED
,
70 cpu_signal_deferred_timer
, "I", "Deferred IPI timeout (nanoseconds)");
72 #endif /* defined(HAS_IPI) */
75 * For source compatibility, here's some machdep.cpu mibs that
76 * use host_info() to simulate reasonable answers.
79 SYSCTL_NODE(_machdep
, OID_AUTO
, cpu
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0,
83 arm_host_info SYSCTL_HANDLER_ARGS
85 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
87 host_basic_info_data_t hinfo
;
88 mach_msg_type_number_t count
= HOST_BASIC_INFO_COUNT
;
90 kern_return_t kret
= host_info((host_t
)BSD_HOST
,
91 HOST_BASIC_INFO
, (host_info_t
)&hinfo
, &count
);
92 if (KERN_SUCCESS
!= kret
) {
96 if (sizeof(uint32_t) != arg2
) {
97 panic("size mismatch");
100 uintptr_t woffset
= (uintptr_t)arg1
/ sizeof(uint32_t);
101 uint32_t datum
= *(uint32_t *)(((uint32_t *)&hinfo
) + woffset
);
102 return SYSCTL_OUT(req
, &datum
, sizeof(datum
));
106 * machdep.cpu.cores_per_package
108 * x86: derived from CPUID data.
109 * ARM: how many physical cores we have in the AP; aka hw.physicalcpu_max
112 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, cores_per_package
,
113 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
114 (void *)offsetof(host_basic_info_data_t
, physical_cpu_max
),
116 arm_host_info
, "I", "CPU cores per package");
119 * machdep.cpu.core_count
121 * x86: derived from CPUID data.
122 * ARM: # active physical cores in the AP; aka hw.physicalcpu
125 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, core_count
,
126 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
127 (void *)offsetof(host_basic_info_data_t
, physical_cpu
),
129 arm_host_info
, "I", "Number of enabled cores per package");
132 * machdep.cpu.logical_per_package
134 * x86: derived from CPUID data. Returns ENOENT if HTT bit not set, but
135 * most x64 CPUs have that, so assume it's available.
136 * ARM: total # logical cores in the AP; aka hw.logicalcpu_max
139 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, logical_per_package
,
140 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
141 (void *)offsetof(host_basic_info_data_t
, logical_cpu_max
),
143 arm_host_info
, "I", "CPU logical cpus per package");
146 * machdep.cpu.thread_count
148 * x86: derived from CPUID data.
149 * ARM: # active logical cores in the AP; aka hw.logicalcpu
152 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, thread_count
,
153 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
154 (void *)offsetof(host_basic_info_data_t
, logical_cpu
),
156 arm_host_info
, "I", "Number of enabled threads per package");
159 * machdep.cpu.brand_string
161 * x86: derived from CPUID data.
162 * ARM: cons something up from the CPUID register. Could include cpufamily
163 * here and map it to a "marketing" name, but there's no obvious need;
164 * the value is already exported via the commpage. So keep it simple.
167 make_brand_string SYSCTL_HANDLER_ARGS
169 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
170 __unused
void *unused_arg1
= arg1
;
171 __unused
int unused_arg2
= arg2
;
175 switch (cpuid_info()->arm_info
.arm_implementor
) {
183 impl
= "ARM architecture";
187 snprintf(buf
, sizeof(buf
), "%s processor", impl
);
188 return SYSCTL_OUT(req
, buf
, strlen(buf
) + 1);
191 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, brand_string
,
192 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
193 0, 0, make_brand_string
, "A", "CPU brand string");
196 SYSCTL_INT(_machdep
, OID_AUTO
, lck_mtx_adaptive_spin_mode
,
197 CTLFLAG_RW
, &lck_mtx_adaptive_spin_mode
, 0,
198 "Enable adaptive spin behavior for kernel mutexes");
201 #if DEVELOPMENT || DEBUG
202 extern uint64_t TLockTimeOut
;
203 SYSCTL_QUAD(_machdep
, OID_AUTO
, tlto
,
204 CTLFLAG_RW
| CTLFLAG_LOCKED
, &TLockTimeOut
,
205 "Ticket spinlock timeout (MATUs): use with care");
208 sysctl_sysreg_vbar_el1 SYSCTL_HANDLER_ARGS
210 #pragma unused(arg1, arg2, oidp)
211 uint64_t return_value
= __builtin_arm_rsr64("VBAR_EL1");
212 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
216 * machdep.cpu.sysreg_vbar_el1
218 * ARM64: Vector Base Address Register.
219 * Read from the current CPU's system registers.
221 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_vbar_el1
,
222 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
223 0, 0, sysctl_sysreg_vbar_el1
, "Q",
224 "VBAR_EL1 register on the current CPU");
227 sysctl_sysreg_mair_el1 SYSCTL_HANDLER_ARGS
229 #pragma unused(arg1, arg2, oidp)
230 uint64_t return_value
= __builtin_arm_rsr64("MAIR_EL1");
231 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
235 * machdep.cpu.sysreg_mair_el1
237 * ARM64: Memory Attribute Indirection Register.
238 * Read from the current CPU's system registers.
240 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_mair_el1
,
241 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
242 0, 0, sysctl_sysreg_mair_el1
, "Q",
243 "MAIR_EL1 register on the current CPU");
246 sysctl_sysreg_ttbr1_el1 SYSCTL_HANDLER_ARGS
248 #pragma unused(arg1, arg2, oidp)
249 uint64_t return_value
= __builtin_arm_rsr64("TTBR1_EL1");
250 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
254 * machdep.cpu.sysreg_ttbr1_el1
256 * ARM64: Translation table base register 1.
257 * Read from the current CPU's system registers.
259 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_ttbr1_el1
,
260 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
261 0, 0, sysctl_sysreg_ttbr1_el1
, "Q",
262 "TTBR1_EL1 register on the current CPU");
265 sysctl_sysreg_sctlr_el1 SYSCTL_HANDLER_ARGS
267 #pragma unused(arg1, arg2, oidp)
268 uint64_t return_value
= __builtin_arm_rsr64("SCTLR_EL1");
269 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
273 * machdep.cpu.sysreg_sctlr_el1
275 * ARM64: System Control Register.
276 * Read from the current CPU's system registers.
278 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_sctlr_el1
,
279 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
280 0, 0, sysctl_sysreg_sctlr_el1
, "Q",
281 "SCTLR_EL1 register on the current CPU");
284 sysctl_sysreg_tcr_el1 SYSCTL_HANDLER_ARGS
286 #pragma unused(arg1, arg2, oidp)
287 uint64_t return_value
= __builtin_arm_rsr64("TCR_EL1");
288 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
292 * machdep.cpu.sysreg_tcr_el1
294 * ARM64: Translation Control Register.
295 * Read from the current CPU's system registers.
297 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_tcr_el1
,
298 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
299 0, 0, sysctl_sysreg_tcr_el1
, "Q",
300 "TCR_EL1 register on the current CPU");
303 sysctl_sysreg_id_aa64mmfr0_el1 SYSCTL_HANDLER_ARGS
305 #pragma unused(arg1, arg2, oidp)
306 uint64_t return_value
= __builtin_arm_rsr64("ID_AA64MMFR0_EL1");
307 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
311 * machdep.cpu.sysreg_id_aa64mmfr0_el1
313 * ARM64: AArch64 Memory Model Feature Register 0.
314 * Read from the current CPU's system registers.
316 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, sysreg_id_aa64mmfr0_el1
,
317 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
318 0, 0, sysctl_sysreg_id_aa64mmfr0_el1
, "Q",
319 "ID_AA64MMFR0_EL1 register on the current CPU");