xref: /xnu-8019.80.24/bsd/dev/arm/sysctl.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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 int      trap_on_alignment_fault;
16 extern uint64_t wake_abstime;
17 extern int      lck_mtx_adaptive_spin_mode;
18 
19 static
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)");
23 
24 static
25 SYSCTL_QUAD(_machdep, OID_AUTO, wake_abstime,
26     CTLFLAG_RD | CTLFLAG_KERN, &wake_abstime,
27     "Absolute Time at the last wakeup");
28 
29 static int
30 sysctl_time_since_reset SYSCTL_HANDLER_ARGS
31 {
32 #pragma unused(arg1, arg2, oidp)
33 	int error = 0;
34 	uint64_t return_value = 0;
35 
36 	return_value = ml_get_time_since_reset();
37 
38 	SYSCTL_OUT(req, &return_value, sizeof(return_value));
39 
40 	return error;
41 }
42 
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");
47 
48 static int
49 sysctl_wake_conttime SYSCTL_HANDLER_ARGS
50 {
51 #pragma unused(arg1, arg2, oidp)
52 	int error = 0;
53 	uint64_t return_value = 0;
54 
55 	return_value = ml_get_conttime_wake_time();
56 
57 	SYSCTL_OUT(req, &return_value, sizeof(return_value));
58 
59 	return error;
60 }
61 
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");
66 
67 /*
68  * For source compatibility, here's some machdep.cpu mibs that
69  * use host_info() to simulate reasonable answers.
70  */
71 
72 SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
73     "CPU info");
74 
75 static int
76 arm_host_info SYSCTL_HANDLER_ARGS
77 {
78 	__unused struct sysctl_oid *unused_oidp = oidp;
79 
80 	host_basic_info_data_t hinfo;
81 	mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
82 #define BSD_HOST        1
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) {
86 		return EINVAL;
87 	}
88 
89 	if (sizeof(uint32_t) != arg2) {
90 		panic("size mismatch");
91 	}
92 
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));
96 }
97 
98 /*
99  * machdep.cpu.cores_per_package
100  *
101  * x86: derived from CPUID data.
102  * ARM: how many physical cores we have in the AP; aka hw.physicalcpu_max
103  */
104 static
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),
108     sizeof(integer_t),
109     arm_host_info, "I", "CPU cores per package");
110 
111 /*
112  * machdep.cpu.core_count
113  *
114  * x86: derived from CPUID data.
115  * ARM: # active physical cores in the AP; aka hw.physicalcpu
116  */
117 static
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),
121     sizeof(integer_t),
122     arm_host_info, "I", "Number of enabled cores per package");
123 
124 /*
125  * machdep.cpu.logical_per_package
126  *
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
130  */
131 static
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),
135     sizeof(integer_t),
136     arm_host_info, "I", "CPU logical cpus per package");
137 
138 /*
139  * machdep.cpu.thread_count
140  *
141  * x86: derived from CPUID data.
142  * ARM: # active logical cores in the AP; aka hw.logicalcpu
143  */
144 static
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),
148     sizeof(integer_t),
149     arm_host_info, "I", "Number of enabled threads per package");
150 
151 /*
152  * machdep.cpu.brand_string
153  *
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.
158  */
159 static int
160 make_brand_string SYSCTL_HANDLER_ARGS
161 {
162 	__unused struct sysctl_oid *unused_oidp = oidp;
163 	__unused void *unused_arg1 = arg1;
164 	__unused int unused_arg2 = arg2;
165 
166 	const char *impl;
167 
168 	switch (cpuid_info()->arm_info.arm_implementor) {
169 	case CPU_VID_APPLE:
170 		impl = "Apple";
171 		break;
172 	case CPU_VID_ARM:
173 		impl = "ARM";
174 		break;
175 	default:
176 		impl = "ARM architecture";
177 		break;
178 	}
179 	char buf[80];
180 	snprintf(buf, sizeof(buf), "%s processor", impl);
181 	return SYSCTL_OUT(req, buf, strlen(buf) + 1);
182 }
183 
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");
187 
188 static
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");
192 
193 static int
194 virtual_address_size SYSCTL_HANDLER_ARGS
195 {
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));
199 }
200 
201 static
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");
206