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 int trap_on_alignment_fault
;
16 extern uint64_t wake_abstime
;
17 extern int lck_mtx_adaptive_spin_mode
;
20 SYSCTL_INT(_machdep
, OID_AUTO
, alignmenttrap
,
21 CTLFLAG_RW
, &trap_on_alignment_fault
, 0,
22 "trap on alignment faults (number of alignment faults per trap)");
25 SYSCTL_QUAD(_machdep
, OID_AUTO
, wake_abstime
,
26 CTLFLAG_RD
| CTLFLAG_KERN
, &wake_abstime
,
27 "Absolute Time at the last wakeup");
30 sysctl_time_since_reset SYSCTL_HANDLER_ARGS
32 #pragma unused(arg1, arg2, oidp)
34 uint64_t return_value
= 0;
36 return_value
= ml_get_time_since_reset();
38 SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
43 SYSCTL_PROC(_machdep
, OID_AUTO
, time_since_reset
,
44 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
45 0, 0, sysctl_time_since_reset
, "I",
46 "Continuous time since last SOC boot/wake started");
49 sysctl_wake_conttime SYSCTL_HANDLER_ARGS
51 #pragma unused(arg1, arg2, oidp)
53 uint64_t return_value
= 0;
55 return_value
= ml_get_conttime_wake_time();
57 SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
62 SYSCTL_PROC(_machdep
, OID_AUTO
, wake_conttime
,
63 CTLFLAG_RD
| CTLTYPE_QUAD
| CTLFLAG_LOCKED
,
64 0, 0, sysctl_wake_conttime
, "I",
65 "Continuous Time at the last wakeup");
68 * For source compatibility, here's some machdep.cpu mibs that
69 * use host_info() to simulate reasonable answers.
72 SYSCTL_NODE(_machdep
, OID_AUTO
, cpu
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0,
76 arm_host_info SYSCTL_HANDLER_ARGS
78 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
80 host_basic_info_data_t hinfo
;
81 mach_msg_type_number_t count
= HOST_BASIC_INFO_COUNT
;
83 kern_return_t kret
= host_info((host_t
)BSD_HOST
,
84 HOST_BASIC_INFO
, (host_info_t
)&hinfo
, &count
);
85 if (KERN_SUCCESS
!= kret
) {
89 if (sizeof(uint32_t) != arg2
) {
90 panic("size mismatch");
93 uintptr_t woffset
= (uintptr_t)arg1
/ sizeof(uint32_t);
94 uint32_t datum
= *(uint32_t *)(((uint32_t *)&hinfo
) + woffset
);
95 return SYSCTL_OUT(req
, &datum
, sizeof(datum
));
99 * machdep.cpu.cores_per_package
101 * x86: derived from CPUID data.
102 * ARM: how many physical cores we have in the AP; aka hw.physicalcpu_max
105 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, cores_per_package
,
106 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
107 (void *)offsetof(host_basic_info_data_t
, physical_cpu_max
),
109 arm_host_info
, "I", "CPU cores per package");
112 * machdep.cpu.core_count
114 * x86: derived from CPUID data.
115 * ARM: # active physical cores in the AP; aka hw.physicalcpu
118 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, core_count
,
119 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
120 (void *)offsetof(host_basic_info_data_t
, physical_cpu
),
122 arm_host_info
, "I", "Number of enabled cores per package");
125 * machdep.cpu.logical_per_package
127 * x86: derived from CPUID data. Returns ENOENT if HTT bit not set, but
128 * most x64 CPUs have that, so assume it's available.
129 * ARM: total # logical cores in the AP; aka hw.logicalcpu_max
132 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, logical_per_package
,
133 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
134 (void *)offsetof(host_basic_info_data_t
, logical_cpu_max
),
136 arm_host_info
, "I", "CPU logical cpus per package");
139 * machdep.cpu.thread_count
141 * x86: derived from CPUID data.
142 * ARM: # active logical cores in the AP; aka hw.logicalcpu
145 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, thread_count
,
146 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
147 (void *)offsetof(host_basic_info_data_t
, logical_cpu
),
149 arm_host_info
, "I", "Number of enabled threads per package");
152 * machdep.cpu.brand_string
154 * x86: derived from CPUID data.
155 * ARM: cons something up from the CPUID register. Could include cpufamily
156 * here and map it to a "marketing" name, but there's no obvious need;
157 * the value is already exported via the commpage. So keep it simple.
160 make_brand_string SYSCTL_HANDLER_ARGS
162 __unused
struct sysctl_oid
*unused_oidp
= oidp
;
163 __unused
void *unused_arg1
= arg1
;
164 __unused
int unused_arg2
= arg2
;
168 switch (cpuid_info()->arm_info
.arm_implementor
) {
176 impl
= "ARM architecture";
180 snprintf(buf
, sizeof(buf
), "%s processor", impl
);
181 return SYSCTL_OUT(req
, buf
, strlen(buf
) + 1);
184 SYSCTL_PROC(_machdep_cpu
, OID_AUTO
, brand_string
,
185 CTLTYPE_STRING
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
186 0, 0, make_brand_string
, "A", "CPU brand string");
189 SYSCTL_INT(_machdep
, OID_AUTO
, lck_mtx_adaptive_spin_mode
,
190 CTLFLAG_RW
, &lck_mtx_adaptive_spin_mode
, 0,
191 "Enable adaptive spin behavior for kernel mutexes");
194 virtual_address_size SYSCTL_HANDLER_ARGS
196 #pragma unused(arg1, arg2, oidp)
197 int return_value
= 32 - (TTBCR_N_SETUP
& TTBCR_N_MASK
);
198 return SYSCTL_OUT(req
, &return_value
, sizeof(return_value
));
202 SYSCTL_PROC(_machdep
, OID_AUTO
, virtual_address_size
,
203 CTLTYPE_INT
| CTLFLAG_RD
| CTLFLAG_LOCKED
,
204 0, 0, virtual_address_size
, "I",
205 "Number of addressable bits in userspace virtual addresses");