]>
Commit | Line | Data |
---|---|---|
55e303ae | 1 | /* |
f427ee49 | 2 | * Copyright (c) 2003-2020 Apple Inc. All rights reserved. |
5d5c5d0d | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
0a7de745 | 5 | * |
2d21ac55 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
0a7de745 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
0a7de745 | 17 | * |
2d21ac55 A |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
0a7de745 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
55e303ae A |
27 | */ |
28 | ||
91447636 | 29 | #include <string.h> |
55e303ae A |
30 | #include <sys/param.h> |
31 | #include <sys/kernel.h> | |
32 | #include <sys/sysctl.h> | |
33 | #include <i386/cpuid.h> | |
593a1d5f | 34 | #include <i386/tsc.h> |
4bd07ac2 | 35 | #include <i386/rtclock_protos.h> |
060df5ea | 36 | #include <i386/machine_routines.h> |
bd504ef0 | 37 | #include <i386/pal_routines.h> |
6d2010ae A |
38 | #include <i386/ucode.h> |
39 | #include <kern/clock.h> | |
40 | #include <libkern/libkern.h> | |
316670eb | 41 | #include <i386/lapic.h> |
39037602 | 42 | #include <i386/mp.h> |
f427ee49 | 43 | #include <kern/kalloc.h> |
bd504ef0 | 44 | |
c3c9b80d A |
45 | #if DEBUG || DEVELOPMENT |
46 | #include <kern/hvg_hypercall.h> | |
47 | #endif | |
48 | ||
55e303ae A |
49 | |
50 | static int | |
7e4a7d39 | 51 | _i386_cpu_info SYSCTL_HANDLER_ARGS |
55e303ae | 52 | { |
0a7de745 A |
53 | __unused struct sysctl_oid *unused_oidp = oidp; |
54 | void *ptr = arg1; | |
55 | int value; | |
56 | ||
57 | if (arg2 == -1) { | |
58 | ptr = *(void **)ptr; | |
59 | arg2 = 0; | |
60 | } | |
61 | ||
62 | if (arg2 == 0 && ((char *)ptr)[0] == '\0') { | |
63 | return ENOENT; | |
64 | } | |
65 | ||
66 | if (arg2 == sizeof(uint8_t)) { | |
67 | value = (uint32_t) *(uint8_t *)ptr; | |
68 | ptr = &value; | |
69 | arg2 = sizeof(uint32_t); | |
70 | } | |
71 | return SYSCTL_OUT(req, ptr, arg2 ? (size_t) arg2 : strlen((char *)ptr) + 1); | |
55e303ae A |
72 | } |
73 | ||
b0d623f7 | 74 | static int |
7e4a7d39 | 75 | i386_cpu_info SYSCTL_HANDLER_ARGS |
b0d623f7 | 76 | { |
0a7de745 A |
77 | void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1; |
78 | return _i386_cpu_info(oidp, ptr, arg2, req); | |
7e4a7d39 A |
79 | } |
80 | ||
81 | static int | |
82 | i386_cpu_info_nonzero SYSCTL_HANDLER_ARGS | |
83 | { | |
0a7de745 A |
84 | void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1; |
85 | int value = *(uint32_t *)ptr; | |
b0d623f7 | 86 | |
0a7de745 A |
87 | if (value == 0) { |
88 | return ENOENT; | |
89 | } | |
b0d623f7 | 90 | |
0a7de745 | 91 | return _i386_cpu_info(oidp, ptr, arg2, req); |
7e4a7d39 A |
92 | } |
93 | static int | |
94 | cpu_mwait SYSCTL_HANDLER_ARGS | |
95 | { | |
0a7de745 A |
96 | i386_cpu_info_t *cpu_info = cpuid_info(); |
97 | void *ptr = (uint8_t *)cpu_info->cpuid_mwait_leafp + (uintptr_t)arg1; | |
98 | if (cpu_info->cpuid_mwait_leafp == NULL) { | |
99 | return ENOENT; | |
100 | } | |
101 | return _i386_cpu_info(oidp, ptr, arg2, req); | |
7e4a7d39 A |
102 | } |
103 | ||
104 | static int | |
105 | cpu_thermal SYSCTL_HANDLER_ARGS | |
106 | { | |
0a7de745 A |
107 | i386_cpu_info_t *cpu_info = cpuid_info(); |
108 | void *ptr = (uint8_t *)cpu_info->cpuid_thermal_leafp + (uintptr_t)arg1; | |
109 | if (cpu_info->cpuid_thermal_leafp == NULL) { | |
110 | return ENOENT; | |
111 | } | |
112 | return _i386_cpu_info(oidp, ptr, arg2, req); | |
7e4a7d39 A |
113 | } |
114 | ||
115 | static int | |
116 | cpu_arch_perf SYSCTL_HANDLER_ARGS | |
117 | { | |
0a7de745 A |
118 | i386_cpu_info_t *cpu_info = cpuid_info(); |
119 | void *ptr = (uint8_t *)cpu_info->cpuid_arch_perf_leafp + (uintptr_t)arg1; | |
120 | if (cpu_info->cpuid_arch_perf_leafp == NULL) { | |
121 | return ENOENT; | |
122 | } | |
123 | return _i386_cpu_info(oidp, ptr, arg2, req); | |
b0d623f7 A |
124 | } |
125 | ||
060df5ea A |
126 | static int |
127 | cpu_xsave SYSCTL_HANDLER_ARGS | |
128 | { | |
0a7de745 A |
129 | i386_cpu_info_t *cpu_info = cpuid_info(); |
130 | void *ptr = (uint8_t *)cpu_info->cpuid_xsave_leafp + (uintptr_t)arg1; | |
131 | if (cpu_info->cpuid_xsave_leafp == NULL) { | |
132 | return ENOENT; | |
133 | } | |
134 | return _i386_cpu_info(oidp, ptr, arg2, req); | |
060df5ea A |
135 | } |
136 | ||
316670eb | 137 | |
55e303ae | 138 | static int |
7e4a7d39 | 139 | cpu_features SYSCTL_HANDLER_ARGS |
55e303ae | 140 | { |
0a7de745 A |
141 | __unused struct sysctl_oid *unused_oidp = oidp; |
142 | __unused void *unused_arg1 = arg1; | |
143 | __unused int unused_arg2 = arg2; | |
144 | char buf[512]; | |
55e303ae | 145 | |
0a7de745 A |
146 | buf[0] = '\0'; |
147 | cpuid_get_feature_names(cpuid_features(), buf, sizeof(buf)); | |
55e303ae | 148 | |
0a7de745 | 149 | return SYSCTL_OUT(req, buf, strlen(buf) + 1); |
55e303ae A |
150 | } |
151 | ||
0c530ab8 | 152 | static int |
7e4a7d39 | 153 | cpu_extfeatures SYSCTL_HANDLER_ARGS |
0c530ab8 | 154 | { |
0a7de745 A |
155 | __unused struct sysctl_oid *unused_oidp = oidp; |
156 | __unused void *unused_arg1 = arg1; | |
157 | __unused int unused_arg2 = arg2; | |
158 | char buf[512]; | |
0c530ab8 | 159 | |
0a7de745 A |
160 | buf[0] = '\0'; |
161 | cpuid_get_extfeature_names(cpuid_extfeatures(), buf, sizeof(buf)); | |
0c530ab8 | 162 | |
0a7de745 | 163 | return SYSCTL_OUT(req, buf, strlen(buf) + 1); |
0c530ab8 A |
164 | } |
165 | ||
13f56ec4 A |
166 | static int |
167 | cpu_leaf7_features SYSCTL_HANDLER_ARGS | |
168 | { | |
0a7de745 A |
169 | __unused struct sysctl_oid *unused_oidp = oidp; |
170 | __unused void *unused_arg1 = arg1; | |
171 | __unused int unused_arg2 = arg2; | |
172 | char buf[512]; | |
13f56ec4 | 173 | |
0a7de745 A |
174 | uint64_t leaf7_features = cpuid_info()->cpuid_leaf7_features; |
175 | uint64_t leaf7_extfeatures = cpuid_info()->cpuid_leaf7_extfeatures; | |
176 | if (leaf7_features == 0 && leaf7_extfeatures == 0) { | |
177 | return ENOENT; | |
178 | } | |
13f56ec4 | 179 | |
0a7de745 A |
180 | buf[0] = '\0'; |
181 | cpuid_get_leaf7_feature_names(leaf7_features, buf, sizeof(buf)); | |
182 | if (leaf7_extfeatures != 0) { | |
183 | strlcat(buf, " ", sizeof(buf)); | |
184 | cpuid_get_leaf7_extfeature_names(leaf7_extfeatures, buf + strlen(buf), | |
f427ee49 | 185 | (unsigned int)(sizeof(buf) - strlen(buf))); |
0a7de745 | 186 | } |
13f56ec4 | 187 | |
0a7de745 | 188 | return SYSCTL_OUT(req, buf, strlen(buf) + 1); |
13f56ec4 A |
189 | } |
190 | ||
2d21ac55 | 191 | static int |
7e4a7d39 | 192 | cpu_logical_per_package SYSCTL_HANDLER_ARGS |
2d21ac55 A |
193 | { |
194 | __unused struct sysctl_oid *unused_oidp = oidp; | |
195 | __unused void *unused_arg1 = arg1; | |
196 | __unused int unused_arg2 = arg2; | |
197 | i386_cpu_info_t *cpu_info = cpuid_info(); | |
198 | ||
0a7de745 | 199 | if (!(cpuid_features() & CPUID_FEATURE_HTT)) { |
2d21ac55 | 200 | return ENOENT; |
0a7de745 | 201 | } |
2d21ac55 A |
202 | |
203 | return SYSCTL_OUT(req, &cpu_info->cpuid_logical_per_package, | |
0a7de745 | 204 | sizeof(cpu_info->cpuid_logical_per_package)); |
2d21ac55 A |
205 | } |
206 | ||
c910b4d9 | 207 | static int |
7e4a7d39 | 208 | cpu_flex_ratio_desired SYSCTL_HANDLER_ARGS |
c910b4d9 A |
209 | { |
210 | __unused struct sysctl_oid *unused_oidp = oidp; | |
211 | __unused void *unused_arg1 = arg1; | |
212 | __unused int unused_arg2 = arg2; | |
213 | i386_cpu_info_t *cpu_info = cpuid_info(); | |
214 | ||
0a7de745 | 215 | if (cpu_info->cpuid_model != 26) { |
c910b4d9 | 216 | return ENOENT; |
0a7de745 | 217 | } |
c910b4d9 A |
218 | |
219 | return SYSCTL_OUT(req, &flex_ratio, sizeof(flex_ratio)); | |
220 | } | |
221 | ||
222 | static int | |
7e4a7d39 | 223 | cpu_flex_ratio_min SYSCTL_HANDLER_ARGS |
c910b4d9 A |
224 | { |
225 | __unused struct sysctl_oid *unused_oidp = oidp; | |
226 | __unused void *unused_arg1 = arg1; | |
227 | __unused int unused_arg2 = arg2; | |
228 | i386_cpu_info_t *cpu_info = cpuid_info(); | |
229 | ||
0a7de745 | 230 | if (cpu_info->cpuid_model != 26) { |
c910b4d9 | 231 | return ENOENT; |
0a7de745 | 232 | } |
c910b4d9 A |
233 | |
234 | return SYSCTL_OUT(req, &flex_ratio_min, sizeof(flex_ratio_min)); | |
235 | } | |
236 | ||
237 | static int | |
7e4a7d39 | 238 | cpu_flex_ratio_max SYSCTL_HANDLER_ARGS |
c910b4d9 A |
239 | { |
240 | __unused struct sysctl_oid *unused_oidp = oidp; | |
241 | __unused void *unused_arg1 = arg1; | |
242 | __unused int unused_arg2 = arg2; | |
243 | i386_cpu_info_t *cpu_info = cpuid_info(); | |
244 | ||
0a7de745 | 245 | if (cpu_info->cpuid_model != 26) { |
c910b4d9 | 246 | return ENOENT; |
0a7de745 | 247 | } |
c910b4d9 A |
248 | |
249 | return SYSCTL_OUT(req, &flex_ratio_max, sizeof(flex_ratio_max)); | |
250 | } | |
251 | ||
6d2010ae A |
252 | static int |
253 | cpu_ucode_update SYSCTL_HANDLER_ARGS | |
254 | { | |
f427ee49 | 255 | #pragma unused(oidp, arg1, arg2) |
6d2010ae A |
256 | uint64_t addr; |
257 | int error; | |
0a7de745 | 258 | |
f427ee49 A |
259 | /* Can't update microcode from within a VM. */ |
260 | ||
261 | if (cpuid_features() & CPUID_FEATURE_VMM) { | |
262 | return ENODEV; | |
263 | } | |
264 | ||
265 | if (req->newptr == USER_ADDR_NULL) { | |
266 | return EINVAL; | |
267 | } | |
268 | ||
6d2010ae | 269 | error = SYSCTL_IN(req, &addr, sizeof(addr)); |
0a7de745 | 270 | if (error) { |
6d2010ae | 271 | return error; |
0a7de745 | 272 | } |
6d2010ae | 273 | |
f427ee49 | 274 | return ucode_interface(addr); |
6d2010ae A |
275 | } |
276 | ||
277 | extern uint64_t panic_restart_timeout; | |
278 | static int | |
279 | panic_set_restart_timeout(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
280 | { | |
281 | int new_value = 0, old_value = 0, changed = 0, error; | |
282 | uint64_t nstime; | |
283 | ||
284 | if (panic_restart_timeout) { | |
285 | absolutetime_to_nanoseconds(panic_restart_timeout, &nstime); | |
f427ee49 | 286 | old_value = (int)MIN(nstime / NSEC_PER_SEC, INT_MAX); |
6d2010ae A |
287 | } |
288 | ||
f427ee49 | 289 | error = sysctl_io_number(req, old_value, sizeof(old_value), &new_value, &changed); |
6d2010ae | 290 | if (error == 0 && changed) { |
f427ee49 A |
291 | if (new_value >= 0) { |
292 | nanoseconds_to_absolutetime(((uint64_t)new_value) * NSEC_PER_SEC, &panic_restart_timeout); | |
293 | } else { | |
294 | error = EDOM; | |
295 | } | |
6d2010ae A |
296 | } |
297 | return error; | |
298 | } | |
299 | ||
060df5ea A |
300 | /* |
301 | * Populates the {CPU, vector, latency} triple for the maximum observed primary | |
302 | * interrupt latency | |
303 | */ | |
304 | static int | |
305 | misc_interrupt_latency_max(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
306 | { | |
307 | int changed = 0, error; | |
308 | char buf[128]; | |
309 | buf[0] = '\0'; | |
310 | ||
311 | interrupt_populate_latency_stats(buf, sizeof(buf)); | |
312 | ||
313 | error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed); | |
314 | ||
315 | if (error == 0 && changed) { | |
316 | interrupt_reset_latency_stats(); | |
317 | } | |
318 | ||
319 | return error; | |
320 | } | |
321 | ||
39037602 | 322 | #if DEVELOPMENT || DEBUG |
f427ee49 A |
323 | /* |
324 | * Populates a string with each CPU's tsc synch delta. | |
325 | */ | |
326 | static int | |
327 | x86_cpu_tsc_deltas(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
328 | { | |
329 | int err; | |
330 | uint32_t ncpus = ml_wait_max_cpus(); | |
331 | uint32_t buflen = (2 /* hex digits */ * sizeof(uint64_t) + 3 /* for "0x" + " " */) * ncpus + 1; | |
332 | char *buf = kalloc(buflen); | |
333 | ||
334 | cpu_data_tsc_sync_deltas_string(buf, buflen, 0, ncpus - 1); | |
335 | ||
336 | err = sysctl_io_string(req, buf, buflen, 0, 0); | |
337 | ||
338 | kfree(buf, buflen); | |
339 | ||
340 | return err; | |
341 | } | |
342 | ||
316670eb A |
343 | /* |
344 | * Triggers a machine-check exception - for a suitably configured kernel only. | |
345 | */ | |
346 | extern void mca_exception_panic(void); | |
347 | static int | |
348 | misc_machine_check_panic(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
349 | { | |
350 | int changed = 0, error; | |
351 | char buf[128]; | |
352 | buf[0] = '\0'; | |
353 | ||
354 | error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed); | |
355 | ||
356 | if (error == 0 && changed) { | |
357 | mca_exception_panic(); | |
358 | } | |
359 | return error; | |
360 | } | |
361 | ||
39037602 A |
362 | /* |
363 | * Triggers a non-responsive processor timeout panic - for a suitably configured kernel only. | |
364 | */ | |
365 | static uint64_t kernel_timeout_spin = 0; | |
366 | static int | |
367 | misc_kernel_timeout_spin(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
368 | { | |
0a7de745 A |
369 | uint64_t old_value; |
370 | uint64_t new_value; | |
39037602 A |
371 | int changed = 0, error; |
372 | char buf[128]; | |
373 | buf[0] = '\0'; | |
374 | ||
375 | absolutetime_to_nanoseconds(kernel_timeout_spin, &old_value); | |
376 | ||
377 | error = sysctl_io_number(req, old_value, sizeof(uint64_t), &new_value, &changed); | |
378 | if (error == 0 && changed) { | |
379 | nanoseconds_to_absolutetime(((uint64_t)new_value), &kernel_timeout_spin); | |
380 | kernel_spin(kernel_timeout_spin); | |
381 | } | |
382 | return error; | |
383 | } | |
384 | #endif /* DEVELOPMENT || DEBUG */ | |
385 | ||
316670eb | 386 | |
0a7de745 A |
387 | SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
388 | "CPU info"); | |
55e303ae | 389 | |
0a7de745 A |
390 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_basic, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
391 | (void *)offsetof(i386_cpu_info_t, cpuid_max_basic), sizeof(uint32_t), | |
392 | i386_cpu_info, "IU", "Max Basic Information value"); | |
b0d623f7 | 393 | |
0a7de745 A |
394 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_ext, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
395 | (void *)offsetof(i386_cpu_info_t, cpuid_max_ext), sizeof(uint32_t), | |
396 | i386_cpu_info, "IU", "Max Extended Function Information value"); | |
b0d623f7 | 397 | |
0a7de745 A |
398 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, vendor, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, |
399 | (void *)offsetof(i386_cpu_info_t, cpuid_vendor), 0, | |
400 | i386_cpu_info, "A", "CPU vendor"); | |
55e303ae | 401 | |
0a7de745 A |
402 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand_string, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, |
403 | (void *)offsetof(i386_cpu_info_t, cpuid_brand_string), 0, | |
404 | i386_cpu_info, "A", "CPU brand string"); | |
55e303ae | 405 | |
0a7de745 A |
406 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, family, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
407 | (void *)offsetof(i386_cpu_info_t, cpuid_family), sizeof(uint8_t), | |
408 | i386_cpu_info, "I", "CPU family"); | |
55e303ae | 409 | |
0a7de745 A |
410 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, model, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
411 | (void *)offsetof(i386_cpu_info_t, cpuid_model), sizeof(uint8_t), | |
412 | i386_cpu_info, "I", "CPU model"); | |
55e303ae | 413 | |
0a7de745 A |
414 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, extmodel, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
415 | (void *)offsetof(i386_cpu_info_t, cpuid_extmodel), sizeof(uint8_t), | |
416 | i386_cpu_info, "I", "CPU extended model"); | |
55e303ae | 417 | |
0a7de745 A |
418 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfamily, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
419 | (void *)offsetof(i386_cpu_info_t, cpuid_extfamily), sizeof(uint8_t), | |
420 | i386_cpu_info, "I", "CPU extended family"); | |
55e303ae | 421 | |
0a7de745 A |
422 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, stepping, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
423 | (void *)offsetof(i386_cpu_info_t, cpuid_stepping), sizeof(uint8_t), | |
424 | i386_cpu_info, "I", "CPU stepping"); | |
55e303ae | 425 | |
0a7de745 A |
426 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, feature_bits, CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED, |
427 | (void *)offsetof(i386_cpu_info_t, cpuid_features), sizeof(uint64_t), | |
428 | i386_cpu_info, "IU", "CPU features"); | |
55e303ae | 429 | |
13f56ec4 | 430 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, leaf7_feature_bits, |
0a7de745 A |
431 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
432 | (void *)offsetof(i386_cpu_info_t, cpuid_leaf7_features), | |
433 | sizeof(uint64_t), | |
434 | i386_cpu_info_nonzero, "IU", "CPU Leaf7 features [EBX ECX]"); | |
435 | ||
436 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, leaf7_feature_bits_edx, | |
437 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, | |
438 | (void *)offsetof(i386_cpu_info_t, cpuid_leaf7_extfeatures), | |
439 | sizeof(uint32_t), | |
440 | i386_cpu_info_nonzero, "IU", "CPU Leaf7 features [EDX]"); | |
13f56ec4 | 441 | |
0a7de745 A |
442 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeature_bits, CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED, |
443 | (void *)offsetof(i386_cpu_info_t, cpuid_extfeatures), sizeof(uint64_t), | |
444 | i386_cpu_info, "IU", "CPU extended features"); | |
0c530ab8 | 445 | |
0a7de745 A |
446 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, signature, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
447 | (void *)offsetof(i386_cpu_info_t, cpuid_signature), sizeof(uint32_t), | |
448 | i386_cpu_info, "I", "CPU signature"); | |
55e303ae | 449 | |
0a7de745 A |
450 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
451 | (void *)offsetof(i386_cpu_info_t, cpuid_brand), sizeof(uint8_t), | |
452 | i386_cpu_info, "I", "CPU brand"); | |
55e303ae | 453 | |
0a7de745 A |
454 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, features, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, |
455 | 0, 0, | |
456 | cpu_features, "A", "CPU feature names"); | |
55e303ae | 457 | |
13f56ec4 | 458 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, leaf7_features, |
0a7de745 A |
459 | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, |
460 | 0, 0, | |
461 | cpu_leaf7_features, "A", "CPU Leaf7 feature names"); | |
13f56ec4 | 462 | |
0a7de745 A |
463 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeatures, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, |
464 | 0, 0, | |
465 | cpu_extfeatures, "A", "CPU extended feature names"); | |
0c530ab8 A |
466 | |
467 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, logical_per_package, | |
0a7de745 A |
468 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
469 | 0, 0, | |
470 | cpu_logical_per_package, "I", "CPU logical cpus per package"); | |
0c530ab8 A |
471 | |
472 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, cores_per_package, | |
0a7de745 A |
473 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
474 | (void *)offsetof(i386_cpu_info_t, cpuid_cores_per_package), | |
475 | sizeof(uint32_t), | |
476 | i386_cpu_info, "I", "CPU cores per package"); | |
0c530ab8 | 477 | |
593a1d5f | 478 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, microcode_version, |
0a7de745 A |
479 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
480 | (void *)offsetof(i386_cpu_info_t, cpuid_microcode_version), | |
481 | sizeof(uint32_t), | |
482 | i386_cpu_info, "I", "Microcode version number"); | |
593a1d5f | 483 | |
6d2010ae | 484 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, processor_flag, |
0a7de745 A |
485 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
486 | (void *)offsetof(i386_cpu_info_t, cpuid_processor_flag), | |
487 | sizeof(uint32_t), | |
488 | i386_cpu_info, "I", "CPU processor flag"); | |
6d2010ae | 489 | |
55e303ae | 490 | |
0a7de745 A |
491 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, mwait, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
492 | "mwait"); | |
2d21ac55 A |
493 | |
494 | SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_min, | |
0a7de745 A |
495 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
496 | (void *)offsetof(cpuid_mwait_leaf_t, linesize_min), | |
497 | sizeof(uint32_t), | |
498 | cpu_mwait, "I", "Monitor/mwait minimum line size"); | |
2d21ac55 A |
499 | |
500 | SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_max, | |
0a7de745 A |
501 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
502 | (void *)offsetof(cpuid_mwait_leaf_t, linesize_max), | |
503 | sizeof(uint32_t), | |
504 | cpu_mwait, "I", "Monitor/mwait maximum line size"); | |
2d21ac55 A |
505 | |
506 | SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, extensions, | |
0a7de745 A |
507 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
508 | (void *)offsetof(cpuid_mwait_leaf_t, extensions), | |
509 | sizeof(uint32_t), | |
510 | cpu_mwait, "I", "Monitor/mwait extensions"); | |
2d21ac55 A |
511 | |
512 | SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, sub_Cstates, | |
0a7de745 A |
513 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
514 | (void *)offsetof(cpuid_mwait_leaf_t, sub_Cstates), | |
515 | sizeof(uint32_t), | |
516 | cpu_mwait, "I", "Monitor/mwait sub C-states"); | |
2d21ac55 A |
517 | |
518 | ||
0a7de745 A |
519 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, thermal, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
520 | "thermal"); | |
2d21ac55 A |
521 | |
522 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, sensor, | |
0a7de745 A |
523 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
524 | (void *)offsetof(cpuid_thermal_leaf_t, sensor), | |
525 | sizeof(boolean_t), | |
526 | cpu_thermal, "I", "Thermal sensor present"); | |
2d21ac55 A |
527 | |
528 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, dynamic_acceleration, | |
0a7de745 A |
529 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
530 | (void *)offsetof(cpuid_thermal_leaf_t, dynamic_acceleration), | |
531 | sizeof(boolean_t), | |
532 | cpu_thermal, "I", "Dynamic Acceleration Technology (Turbo Mode)"); | |
2d21ac55 | 533 | |
b7266188 | 534 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, invariant_APIC_timer, |
0a7de745 A |
535 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
536 | (void *)offsetof(cpuid_thermal_leaf_t, invariant_APIC_timer), | |
537 | sizeof(boolean_t), | |
538 | cpu_thermal, "I", "Invariant APIC Timer"); | |
b7266188 | 539 | |
2d21ac55 | 540 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, thresholds, |
0a7de745 A |
541 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
542 | (void *)offsetof(cpuid_thermal_leaf_t, thresholds), | |
543 | sizeof(uint32_t), | |
544 | cpu_thermal, "I", "Number of interrupt thresholds"); | |
2d21ac55 A |
545 | |
546 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, ACNT_MCNT, | |
0a7de745 A |
547 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
548 | (void *)offsetof(cpuid_thermal_leaf_t, ACNT_MCNT), | |
549 | sizeof(boolean_t), | |
550 | cpu_thermal, "I", "ACNT_MCNT capability"); | |
2d21ac55 | 551 | |
060df5ea | 552 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, core_power_limits, |
0a7de745 A |
553 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
554 | (void *)offsetof(cpuid_thermal_leaf_t, core_power_limits), | |
555 | sizeof(boolean_t), | |
556 | cpu_thermal, "I", "Power Limit Notifications at a Core Level"); | |
060df5ea A |
557 | |
558 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, fine_grain_clock_mod, | |
0a7de745 A |
559 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
560 | (void *)offsetof(cpuid_thermal_leaf_t, fine_grain_clock_mod), | |
561 | sizeof(boolean_t), | |
562 | cpu_thermal, "I", "Fine Grain Clock Modulation"); | |
060df5ea A |
563 | |
564 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, package_thermal_intr, | |
0a7de745 A |
565 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
566 | (void *)offsetof(cpuid_thermal_leaf_t, package_thermal_intr), | |
567 | sizeof(boolean_t), | |
568 | cpu_thermal, "I", "Package Thermal interrupt and Status"); | |
060df5ea A |
569 | |
570 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, hardware_feedback, | |
0a7de745 A |
571 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
572 | (void *)offsetof(cpuid_thermal_leaf_t, hardware_feedback), | |
573 | sizeof(boolean_t), | |
574 | cpu_thermal, "I", "Hardware Coordination Feedback"); | |
060df5ea A |
575 | |
576 | SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, energy_policy, | |
0a7de745 A |
577 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
578 | (void *)offsetof(cpuid_thermal_leaf_t, energy_policy), | |
579 | sizeof(boolean_t), | |
580 | cpu_thermal, "I", "Energy Efficient Policy Support"); | |
060df5ea | 581 | |
0a7de745 A |
582 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, xsave, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
583 | "xsave"); | |
060df5ea A |
584 | |
585 | SYSCTL_PROC(_machdep_cpu_xsave, OID_AUTO, extended_state, | |
0a7de745 A |
586 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
587 | (void *) 0, | |
588 | sizeof(cpuid_xsave_leaf_t), | |
589 | cpu_xsave, "IU", "XSAVE Extended State Main Leaf"); | |
3e170ce0 A |
590 | |
591 | SYSCTL_PROC(_machdep_cpu_xsave, OID_AUTO, extended_state1, | |
0a7de745 A |
592 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
593 | (void *) sizeof(cpuid_xsave_leaf_t), | |
594 | sizeof(cpuid_xsave_leaf_t), | |
595 | cpu_xsave, "IU", "XSAVE Extended State Sub-leaf 1"); | |
060df5ea | 596 | |
2d21ac55 | 597 | |
0a7de745 A |
598 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, arch_perf, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
599 | "arch_perf"); | |
2d21ac55 A |
600 | |
601 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, version, | |
0a7de745 A |
602 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
603 | (void *)offsetof(cpuid_arch_perf_leaf_t, version), | |
604 | sizeof(uint8_t), | |
605 | cpu_arch_perf, "I", "Architectural Performance Version Number"); | |
2d21ac55 A |
606 | |
607 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, number, | |
0a7de745 A |
608 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
609 | (void *)offsetof(cpuid_arch_perf_leaf_t, number), | |
610 | sizeof(uint8_t), | |
611 | cpu_arch_perf, "I", "Number of counters per logical cpu"); | |
2d21ac55 A |
612 | |
613 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, width, | |
0a7de745 A |
614 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
615 | (void *)offsetof(cpuid_arch_perf_leaf_t, width), | |
616 | sizeof(uint8_t), | |
617 | cpu_arch_perf, "I", "Bit width of counters"); | |
2d21ac55 A |
618 | |
619 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events_number, | |
0a7de745 A |
620 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
621 | (void *)offsetof(cpuid_arch_perf_leaf_t, events_number), | |
622 | sizeof(uint8_t), | |
623 | cpu_arch_perf, "I", "Number of monitoring events"); | |
2d21ac55 A |
624 | |
625 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events, | |
0a7de745 A |
626 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
627 | (void *)offsetof(cpuid_arch_perf_leaf_t, events), | |
628 | sizeof(uint32_t), | |
629 | cpu_arch_perf, "I", "Bit vector of events"); | |
2d21ac55 A |
630 | |
631 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_number, | |
0a7de745 A |
632 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
633 | (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_number), | |
634 | sizeof(uint8_t), | |
635 | cpu_arch_perf, "I", "Number of fixed-function counters"); | |
2d21ac55 A |
636 | |
637 | SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_width, | |
0a7de745 A |
638 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
639 | (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_width), | |
640 | sizeof(uint8_t), | |
641 | cpu_arch_perf, "I", "Bit-width of fixed-function counters"); | |
2d21ac55 A |
642 | |
643 | ||
0a7de745 A |
644 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, cache, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
645 | "cache"); | |
2d21ac55 A |
646 | |
647 | SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, linesize, | |
0a7de745 A |
648 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
649 | (void *)offsetof(i386_cpu_info_t, cpuid_cache_linesize), | |
650 | sizeof(uint32_t), | |
651 | i386_cpu_info, "I", "Cacheline size"); | |
2d21ac55 A |
652 | |
653 | SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, L2_associativity, | |
0a7de745 A |
654 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
655 | (void *)offsetof(i386_cpu_info_t, cpuid_cache_L2_associativity), | |
656 | sizeof(uint32_t), | |
657 | i386_cpu_info, "I", "L2 cache associativity"); | |
2d21ac55 A |
658 | |
659 | SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, size, | |
0a7de745 A |
660 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
661 | (void *)offsetof(i386_cpu_info_t, cpuid_cache_size), | |
662 | sizeof(uint32_t), | |
663 | i386_cpu_info, "I", "Cache size (in Kbytes)"); | |
2d21ac55 A |
664 | |
665 | ||
0a7de745 A |
666 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, tlb, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
667 | "tlb"); | |
668 | SYSCTL_NODE(_machdep_cpu_tlb, OID_AUTO, inst, CTLFLAG_RW | CTLFLAG_LOCKED, 0, | |
669 | "inst"); | |
670 | SYSCTL_NODE(_machdep_cpu_tlb, OID_AUTO, data, CTLFLAG_RW | CTLFLAG_LOCKED, 0, | |
671 | "data"); | |
b0d623f7 A |
672 | |
673 | SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, small, | |
0a7de745 A |
674 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
675 | (void *)offsetof(i386_cpu_info_t, | |
676 | cpuid_tlb[TLB_INST][TLB_SMALL][0]), | |
677 | sizeof(uint32_t), | |
678 | i386_cpu_info_nonzero, "I", | |
679 | "Number of small page instruction TLBs"); | |
593a1d5f | 680 | |
b0d623f7 | 681 | SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small, |
0a7de745 A |
682 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
683 | (void *)offsetof(i386_cpu_info_t, | |
684 | cpuid_tlb[TLB_DATA][TLB_SMALL][0]), | |
685 | sizeof(uint32_t), | |
686 | i386_cpu_info_nonzero, "I", | |
687 | "Number of small page data TLBs (1st level)"); | |
593a1d5f | 688 | |
b0d623f7 | 689 | SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small_level1, |
0a7de745 A |
690 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
691 | (void *)offsetof(i386_cpu_info_t, | |
692 | cpuid_tlb[TLB_DATA][TLB_SMALL][1]), | |
693 | sizeof(uint32_t), | |
694 | i386_cpu_info_nonzero, "I", | |
695 | "Number of small page data TLBs (2nd level)"); | |
593a1d5f | 696 | |
b0d623f7 | 697 | SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, large, |
0a7de745 A |
698 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
699 | (void *)offsetof(i386_cpu_info_t, | |
700 | cpuid_tlb[TLB_INST][TLB_LARGE][0]), | |
701 | sizeof(uint32_t), | |
702 | i386_cpu_info_nonzero, "I", | |
703 | "Number of large page instruction TLBs"); | |
593a1d5f | 704 | |
b0d623f7 | 705 | SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large, |
0a7de745 A |
706 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
707 | (void *)offsetof(i386_cpu_info_t, | |
708 | cpuid_tlb[TLB_DATA][TLB_LARGE][0]), | |
709 | sizeof(uint32_t), | |
710 | i386_cpu_info_nonzero, "I", | |
711 | "Number of large page data TLBs (1st level)"); | |
b0d623f7 A |
712 | |
713 | SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large_level1, | |
0a7de745 A |
714 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
715 | (void *)offsetof(i386_cpu_info_t, | |
716 | cpuid_tlb[TLB_DATA][TLB_LARGE][1]), | |
717 | sizeof(uint32_t), | |
718 | i386_cpu_info_nonzero, "I", | |
719 | "Number of large page data TLBs (2nd level)"); | |
b0d623f7 A |
720 | |
721 | SYSCTL_PROC(_machdep_cpu_tlb, OID_AUTO, shared, | |
0a7de745 A |
722 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
723 | (void *)offsetof(i386_cpu_info_t, cpuid_stlb), | |
724 | sizeof(uint32_t), | |
725 | i386_cpu_info_nonzero, "I", | |
726 | "Number of shared TLBs"); | |
593a1d5f A |
727 | |
728 | ||
0a7de745 A |
729 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, address_bits, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
730 | "address_bits"); | |
2d21ac55 A |
731 | |
732 | SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, physical, | |
0a7de745 A |
733 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
734 | (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_physical), | |
735 | sizeof(uint32_t), | |
736 | i386_cpu_info, "I", "Number of physical address bits"); | |
2d21ac55 A |
737 | |
738 | SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, virtual, | |
0a7de745 A |
739 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
740 | (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_virtual), | |
741 | sizeof(uint32_t), | |
742 | i386_cpu_info, "I", "Number of virtual address bits"); | |
2d21ac55 | 743 | |
b0d623f7 | 744 | |
593a1d5f | 745 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, core_count, |
0a7de745 A |
746 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
747 | (void *)offsetof(i386_cpu_info_t, core_count), | |
748 | sizeof(uint32_t), | |
749 | i386_cpu_info, "I", "Number of enabled cores per package"); | |
593a1d5f A |
750 | |
751 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, thread_count, | |
0a7de745 A |
752 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
753 | (void *)offsetof(i386_cpu_info_t, thread_count), | |
754 | sizeof(uint32_t), | |
755 | i386_cpu_info, "I", "Number of enabled threads per package"); | |
593a1d5f | 756 | |
0a7de745 A |
757 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, flex_ratio, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
758 | "Flex ratio"); | |
c910b4d9 A |
759 | |
760 | SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, desired, | |
0a7de745 A |
761 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
762 | 0, 0, | |
763 | cpu_flex_ratio_desired, "I", "Flex ratio desired (0 disabled)"); | |
c910b4d9 A |
764 | |
765 | SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, min, | |
0a7de745 A |
766 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
767 | 0, 0, | |
768 | cpu_flex_ratio_min, "I", "Flex ratio min (efficiency)"); | |
c910b4d9 A |
769 | |
770 | SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, max, | |
0a7de745 A |
771 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
772 | 0, 0, | |
773 | cpu_flex_ratio_max, "I", "Flex ratio max (non-turbo)"); | |
593a1d5f | 774 | |
0a7de745 A |
775 | SYSCTL_PROC(_machdep_cpu, OID_AUTO, ucupdate, |
776 | CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_LOCKED, 0, 0, | |
777 | cpu_ucode_update, "S", "Microcode update interface"); | |
6d2010ae | 778 | |
0a7de745 A |
779 | SYSCTL_NODE(_machdep_cpu, OID_AUTO, tsc_ccc, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
780 | "TSC/CCC frequency information"); | |
2dced7af A |
781 | |
782 | SYSCTL_PROC(_machdep_cpu_tsc_ccc, OID_AUTO, numerator, | |
0a7de745 A |
783 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
784 | (void *)offsetof(i386_cpu_info_t, cpuid_tsc_leaf.numerator), | |
785 | sizeof(uint32_t), | |
786 | i386_cpu_info, "I", "Numerator of TSC/CCC ratio"); | |
2dced7af A |
787 | |
788 | SYSCTL_PROC(_machdep_cpu_tsc_ccc, OID_AUTO, denominator, | |
0a7de745 A |
789 | CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, |
790 | (void *)offsetof(i386_cpu_info_t, cpuid_tsc_leaf.denominator), | |
791 | sizeof(uint32_t), | |
792 | i386_cpu_info, "I", "Denominator of TSC/CCC ratio"); | |
2dced7af | 793 | |
316670eb A |
794 | static const uint32_t apic_timer_vector = (LAPIC_DEFAULT_INTERRUPT_BASE + LAPIC_TIMER_INTERRUPT); |
795 | static const uint32_t apic_IPI_vector = (LAPIC_DEFAULT_INTERRUPT_BASE + LAPIC_INTERPROCESSOR_INTERRUPT); | |
796 | ||
797 | SYSCTL_NODE(_machdep, OID_AUTO, vectors, CTLFLAG_RD | CTLFLAG_LOCKED, 0, | |
0a7de745 | 798 | "Interrupt vector assignments"); |
316670eb | 799 | |
0a7de745 A |
800 | SYSCTL_UINT(_machdep_vectors, OID_AUTO, timer, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, __DECONST(uint32_t *, &apic_timer_vector), 0, ""); |
801 | SYSCTL_UINT(_machdep_vectors, OID_AUTO, IPI, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, __DECONST(uint32_t *, &apic_IPI_vector), 0, ""); | |
316670eb | 802 | |
2d21ac55 A |
803 | uint64_t pmap_pv_hashlist_walks; |
804 | uint64_t pmap_pv_hashlist_cnts; | |
805 | uint32_t pmap_pv_hashlist_max; | |
b0d623f7 | 806 | uint32_t pmap_kernel_text_ps = PAGE_SIZE; |
6d2010ae | 807 | extern uint32_t pv_hashed_kern_low_water_mark; |
2d21ac55 A |
808 | |
809 | /*extern struct sysctl_oid_list sysctl__machdep_pmap_children;*/ | |
810 | ||
0a7de745 A |
811 | SYSCTL_NODE(_machdep, OID_AUTO, pmap, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
812 | "PMAP info"); | |
55e303ae | 813 | |
0a7de745 A |
814 | SYSCTL_QUAD(_machdep_pmap, OID_AUTO, hashwalks, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_walks, ""); |
815 | SYSCTL_QUAD(_machdep_pmap, OID_AUTO, hashcnts, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_cnts, ""); | |
816 | SYSCTL_INT(_machdep_pmap, OID_AUTO, hashmax, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_max, 0, ""); | |
817 | SYSCTL_INT(_machdep_pmap, OID_AUTO, kernel_text_ps, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_kernel_text_ps, 0, ""); | |
818 | SYSCTL_INT(_machdep_pmap, OID_AUTO, kern_pv_reserve, CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, &pv_hashed_kern_low_water_mark, 0, ""); | |
b0d623f7 | 819 | |
0a7de745 | 820 | SYSCTL_NODE(_machdep, OID_AUTO, memmap, CTLFLAG_RD | CTLFLAG_LOCKED, NULL, "physical memory map"); |
b0d623f7 A |
821 | |
822 | uint64_t firmware_Conventional_bytes = 0; | |
823 | uint64_t firmware_RuntimeServices_bytes = 0; | |
824 | uint64_t firmware_ACPIReclaim_bytes = 0; | |
825 | uint64_t firmware_ACPINVS_bytes = 0; | |
826 | uint64_t firmware_PalCode_bytes = 0; | |
827 | uint64_t firmware_Reserved_bytes = 0; | |
828 | uint64_t firmware_Unusable_bytes = 0; | |
829 | uint64_t firmware_other_bytes = 0; | |
830 | ||
0a7de745 A |
831 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Conventional, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_Conventional_bytes, ""); |
832 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, RuntimeServices, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_RuntimeServices_bytes, ""); | |
833 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, ACPIReclaim, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_ACPIReclaim_bytes, ""); | |
834 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, ACPINVS, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_ACPINVS_bytes, ""); | |
835 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, PalCode, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_PalCode_bytes, ""); | |
836 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Reserved, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_Reserved_bytes, ""); | |
837 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Unusable, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_Unusable_bytes, ""); | |
838 | SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Other, CTLFLAG_RD | CTLFLAG_LOCKED, &firmware_other_bytes, ""); | |
060df5ea | 839 | |
0a7de745 | 840 | SYSCTL_NODE(_machdep, OID_AUTO, tsc, CTLFLAG_RD | CTLFLAG_LOCKED, NULL, "Timestamp counter parameters"); |
060df5ea | 841 | |
bd504ef0 | 842 | SYSCTL_QUAD(_machdep_tsc, OID_AUTO, frequency, |
0a7de745 | 843 | CTLFLAG_RD | CTLFLAG_LOCKED, &tscFreq, ""); |
bd504ef0 A |
844 | |
845 | extern uint32_t deep_idle_rebase; | |
846 | SYSCTL_UINT(_machdep_tsc, OID_AUTO, deep_idle_rebase, | |
0a7de745 | 847 | CTLFLAG_RD | CTLFLAG_LOCKED, &deep_idle_rebase, 0, ""); |
4bd07ac2 | 848 | SYSCTL_QUAD(_machdep_tsc, OID_AUTO, at_boot, |
0a7de745 | 849 | CTLFLAG_RD | CTLFLAG_LOCKED, &tsc_at_boot, ""); |
4bd07ac2 | 850 | SYSCTL_QUAD(_machdep_tsc, OID_AUTO, rebase_abs_time, |
0a7de745 | 851 | CTLFLAG_RD | CTLFLAG_LOCKED, &tsc_rebase_abs_time, ""); |
f427ee49 A |
852 | #if DEVELOPMENT || DEBUG |
853 | SYSCTL_PROC(_machdep_tsc, OID_AUTO, synch_deltas, | |
854 | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, | |
855 | 0, 0, x86_cpu_tsc_deltas, "A", "TSC synch deltas"); | |
856 | #endif | |
bd504ef0 A |
857 | |
858 | SYSCTL_NODE(_machdep_tsc, OID_AUTO, nanotime, | |
0a7de745 | 859 | CTLFLAG_RD | CTLFLAG_LOCKED, NULL, "TSC to ns conversion"); |
bd504ef0 | 860 | SYSCTL_QUAD(_machdep_tsc_nanotime, OID_AUTO, tsc_base, |
0a7de745 A |
861 | CTLFLAG_RD | CTLFLAG_LOCKED, |
862 | __DECONST(uint64_t *, &pal_rtc_nanotime_info.tsc_base), ""); | |
bd504ef0 | 863 | SYSCTL_QUAD(_machdep_tsc_nanotime, OID_AUTO, ns_base, |
0a7de745 A |
864 | CTLFLAG_RD | CTLFLAG_LOCKED, |
865 | __DECONST(uint64_t *, &pal_rtc_nanotime_info.ns_base), ""); | |
bd504ef0 | 866 | SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, scale, |
0a7de745 A |
867 | CTLFLAG_RD | CTLFLAG_LOCKED, |
868 | __DECONST(uint32_t *, &pal_rtc_nanotime_info.scale), 0, ""); | |
bd504ef0 | 869 | SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, shift, |
0a7de745 A |
870 | CTLFLAG_RD | CTLFLAG_LOCKED, |
871 | __DECONST(uint32_t *, &pal_rtc_nanotime_info.shift), 0, ""); | |
bd504ef0 | 872 | SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, generation, |
0a7de745 A |
873 | CTLFLAG_RD | CTLFLAG_LOCKED, |
874 | __DECONST(uint32_t *, &pal_rtc_nanotime_info.generation), 0, ""); | |
6d2010ae | 875 | |
0a7de745 A |
876 | SYSCTL_NODE(_machdep, OID_AUTO, misc, CTLFLAG_RW | CTLFLAG_LOCKED, 0, |
877 | "Miscellaneous x86 kernel parameters"); | |
060df5ea | 878 | |
5ba3f43e A |
879 | #if (DEVELOPMENT || DEBUG) |
880 | extern uint32_t mp_interrupt_watchdog_events; | |
881 | SYSCTL_UINT(_machdep_misc, OID_AUTO, interrupt_watchdog_events, | |
0a7de745 | 882 | CTLFLAG_RW | CTLFLAG_LOCKED, &mp_interrupt_watchdog_events, 0, ""); |
f427ee49 A |
883 | |
884 | extern int insnstream_force_cacheline_mismatch; | |
885 | SYSCTL_INT(_machdep_misc, OID_AUTO, insnstream_force_clmismatch, | |
886 | CTLFLAG_RW | CTLFLAG_LOCKED, &insnstream_force_cacheline_mismatch, 0, ""); | |
5ba3f43e A |
887 | #endif |
888 | ||
889 | ||
6d2010ae | 890 | SYSCTL_PROC(_machdep_misc, OID_AUTO, panic_restart_timeout, |
0a7de745 A |
891 | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, |
892 | 0, 0, | |
893 | panic_set_restart_timeout, "I", "Panic restart timeout in seconds"); | |
6d2010ae | 894 | |
316670eb | 895 | SYSCTL_PROC(_machdep_misc, OID_AUTO, interrupt_latency_max, |
0a7de745 A |
896 | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, |
897 | 0, 0, | |
898 | misc_interrupt_latency_max, "A", "Maximum Interrupt latency"); | |
316670eb | 899 | |
f427ee49 A |
900 | extern boolean_t is_x2apic; |
901 | SYSCTL_INT(_machdep, OID_AUTO, x2apic_enabled, | |
902 | CTLFLAG_KERN | CTLFLAG_RD | CTLFLAG_LOCKED, | |
903 | &is_x2apic, 0, ""); | |
904 | ||
39037602 | 905 | #if DEVELOPMENT || DEBUG |
316670eb | 906 | SYSCTL_PROC(_machdep_misc, OID_AUTO, machine_check_panic, |
0a7de745 A |
907 | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, |
908 | 0, 0, | |
909 | misc_machine_check_panic, "A", "Machine-check exception test"); | |
316670eb | 910 | |
39037602 | 911 | SYSCTL_PROC(_machdep_misc, OID_AUTO, kernel_timeout_spin, |
0a7de745 A |
912 | CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED, |
913 | 0, sizeof(kernel_timeout_spin), | |
914 | misc_kernel_timeout_spin, "Q", "Kernel timeout panic test"); | |
39037602 | 915 | |
3e170ce0 | 916 | SYSCTL_QUAD(_machdep, OID_AUTO, reportphyreadabs, |
0a7de745 A |
917 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
918 | &reportphyreaddelayabs, ""); | |
919 | SYSCTL_QUAD(_machdep, OID_AUTO, reportphywriteabs, | |
920 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
921 | &reportphywritedelayabs, ""); | |
922 | SYSCTL_QUAD(_machdep, OID_AUTO, tracephyreadabs, | |
923 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
924 | &tracephyreaddelayabs, ""); | |
925 | SYSCTL_QUAD(_machdep, OID_AUTO, tracephywriteabs, | |
926 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
927 | &tracephywritedelayabs, ""); | |
3e170ce0 | 928 | SYSCTL_INT(_machdep, OID_AUTO, reportphyreadosbt, |
0a7de745 A |
929 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
930 | &reportphyreadosbt, 0, ""); | |
931 | SYSCTL_INT(_machdep, OID_AUTO, reportphywriteosbt, | |
932 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
933 | &reportphywriteosbt, 0, ""); | |
813fb2f6 | 934 | SYSCTL_INT(_machdep, OID_AUTO, phyreaddelaypanic, |
0a7de745 A |
935 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
936 | &phyreadpanic, 0, ""); | |
937 | SYSCTL_INT(_machdep, OID_AUTO, phywritedelaypanic, | |
938 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
939 | &phywritepanic, 0, ""); | |
940 | #if DEVELOPMENT || DEBUG | |
941 | extern uint64_t simulate_stretched_io; | |
942 | SYSCTL_QUAD(_machdep, OID_AUTO, sim_stretched_io_ns, | |
943 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
944 | &simulate_stretched_io, ""); | |
945 | #endif | |
39037602 A |
946 | |
947 | extern int pmap_pagezero_mitigation; | |
948 | extern int pmap_asserts_enabled, pmap_asserts_traced; | |
949 | /* On DEV/DEBUG kernels, clear this to disable the SMAP emulation | |
950 | * (address space disconnect) for pagezero-less processes. | |
951 | */ | |
952 | SYSCTL_INT(_machdep, OID_AUTO, pmap_pagezero_mitigation, | |
953 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
954 | &pmap_pagezero_mitigation, 0, ""); | |
955 | /* Toggle pmap assertions */ | |
956 | SYSCTL_INT(_machdep, OID_AUTO, pmap_asserts, | |
957 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
958 | &pmap_asserts_enabled, 0, ""); | |
959 | /* Transform pmap assertions into kernel trace terminations */ | |
960 | SYSCTL_INT(_machdep, OID_AUTO, pmap_asserts_traced, | |
961 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
962 | &pmap_asserts_traced, 0, ""); | |
963 | ||
964 | static int | |
965 | misc_svisor_read(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
966 | { | |
967 | uint64_t new_value = 0, old_value = 0; | |
968 | int changed = 0, error; | |
969 | ||
970 | error = sysctl_io_number(req, old_value, sizeof(uint64_t), &new_value, &changed); | |
971 | if ((error == 0) && changed) { | |
972 | volatile uint32_t *raddr = (uint32_t *) new_value; | |
973 | printf("Supervisor: value at 0x%llx is 0x%x\n", new_value, *raddr); | |
974 | } | |
975 | return error; | |
976 | } | |
977 | ||
978 | SYSCTL_PROC(_machdep_misc, OID_AUTO, misc_svisor_read, | |
0a7de745 A |
979 | CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED, |
980 | 0, 0, | |
981 | misc_svisor_read, "I", "supervisor mode read"); | |
39037602 A |
982 | |
983 | #endif /* DEVELOPMENT || DEBUG */ | |
39236c6e A |
984 | |
985 | extern void timer_queue_trace_cpu(int); | |
986 | static int | |
987 | misc_timer_queue_trace(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
988 | { | |
989 | int changed = 0, error; | |
990 | char buf[128]; | |
991 | buf[0] = '\0'; | |
992 | ||
993 | error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed); | |
994 | ||
995 | if (error == 0 && changed) { | |
996 | timer_queue_trace_cpu(0); | |
997 | } | |
998 | return error; | |
999 | } | |
1000 | ||
1001 | SYSCTL_PROC(_machdep_misc, OID_AUTO, timer_queue_trace, | |
0a7de745 A |
1002 | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, |
1003 | 0, 0, | |
1004 | misc_timer_queue_trace, "A", "Cut timer queue tracepoint"); | |
39236c6e A |
1005 | |
1006 | extern long NMI_count; | |
1007 | extern void NMI_cpus(void); | |
1008 | static int | |
1009 | misc_nmis(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
1010 | { | |
1011 | int new = 0, old = 0, changed = 0, error; | |
1012 | ||
f427ee49 | 1013 | old = (int)MIN(NMI_count, INT_MAX); |
39236c6e A |
1014 | |
1015 | error = sysctl_io_number(req, old, sizeof(int), &new, &changed); | |
1016 | if (error == 0 && changed) { | |
1017 | NMI_cpus(); | |
1018 | } | |
1019 | ||
1020 | return error; | |
1021 | } | |
1022 | ||
1023 | SYSCTL_PROC(_machdep_misc, OID_AUTO, nmis, | |
0a7de745 A |
1024 | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, |
1025 | 0, 0, | |
1026 | misc_nmis, "I", "Report/increment NMI count"); | |
39236c6e A |
1027 | |
1028 | /* Parameters related to timer coalescing tuning, to be replaced | |
1029 | * with a dedicated systemcall in the future. | |
1030 | */ | |
1031 | /* Enable processing pending timers in the context of any other interrupt */ | |
1032 | SYSCTL_INT(_kern, OID_AUTO, interrupt_timer_coalescing_enabled, | |
0a7de745 A |
1033 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1034 | &interrupt_timer_coalescing_enabled, 0, ""); | |
39236c6e A |
1035 | /* Upon entering idle, process pending timers with HW deadlines |
1036 | * this far in the future. | |
1037 | */ | |
1038 | SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_idle_entry_hard_deadline_max, | |
0a7de745 A |
1039 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1040 | &idle_entry_timer_processing_hdeadline_threshold, 0, ""); | |
39236c6e A |
1041 | |
1042 | /* Track potentially expensive eager timer evaluations on QoS tier | |
1043 | * switches. | |
1044 | */ | |
1045 | extern uint32_t ml_timer_eager_evaluations; | |
1046 | ||
1047 | SYSCTL_INT(_machdep, OID_AUTO, eager_timer_evaluations, | |
0a7de745 A |
1048 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1049 | &ml_timer_eager_evaluations, 0, ""); | |
39236c6e A |
1050 | |
1051 | extern uint64_t ml_timer_eager_evaluation_max; | |
1052 | ||
1053 | SYSCTL_QUAD(_machdep, OID_AUTO, eager_timer_evaluation_max, | |
0a7de745 A |
1054 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1055 | &ml_timer_eager_evaluation_max, ""); | |
3e170ce0 A |
1056 | extern uint64_t x86_isr_fp_simd_use; |
1057 | SYSCTL_QUAD(_machdep, OID_AUTO, x86_fp_simd_isr_uses, | |
0a7de745 A |
1058 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1059 | &x86_isr_fp_simd_use, ""); | |
39037602 A |
1060 | #if DEVELOPMENT || DEBUG |
1061 | ||
1062 | extern int plctrace_enabled; | |
1063 | ||
1064 | SYSCTL_INT(_machdep, OID_AUTO, pltrace, | |
0a7de745 A |
1065 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1066 | &plctrace_enabled, 0, ""); | |
1067 | ||
1068 | /* Intentionally not declared as volatile here: */ | |
1069 | extern int mmiotrace_enabled; | |
1070 | ||
1071 | SYSCTL_INT(_machdep, OID_AUTO, MMIOtrace, | |
1072 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
1073 | &mmiotrace_enabled, 0, ""); | |
d26ffc64 A |
1074 | |
1075 | extern int fpsimd_fault_popc; | |
1076 | SYSCTL_INT(_machdep, OID_AUTO, fpsimd_fault_popc, | |
0a7de745 A |
1077 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, |
1078 | &fpsimd_fault_popc, 0, ""); | |
1079 | ||
cb323159 A |
1080 | volatile int stop_spinning; |
1081 | static int | |
1082 | spin_in_the_kernel(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) | |
1083 | { | |
1084 | int new = 0, old = 0, changed = 0, error; | |
1085 | ||
1086 | error = sysctl_io_number(req, old, sizeof(int), &new, &changed); | |
1087 | if (error == 0 && changed) { | |
1088 | stop_spinning = FALSE; | |
1089 | while (stop_spinning == FALSE) { | |
1090 | __builtin_ia32_pause(); | |
1091 | } | |
1092 | } else if (error == 0) { | |
1093 | stop_spinning = TRUE; | |
1094 | } | |
1095 | ||
1096 | return error; | |
1097 | } | |
1098 | ||
1099 | SYSCTL_PROC(_machdep_misc, OID_AUTO, spin_forever, | |
1100 | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_MASKED, | |
1101 | 0, 0, | |
1102 | spin_in_the_kernel, "I", "Spin forever"); | |
d26ffc64 | 1103 | |
94ff46dc A |
1104 | |
1105 | extern int traptrace_enabled; | |
1106 | SYSCTL_INT(_machdep_misc, OID_AUTO, traptrace_enabled, | |
1107 | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, | |
1108 | &traptrace_enabled, 0, "Enabled/disable trap trace"); | |
1109 | ||
c3c9b80d A |
1110 | |
1111 | /* | |
1112 | * Trigger a guest kernel core dump (internal only) | |
1113 | * Usage: sysctl kern.trigger_kernel_coredump = 1 | |
1114 | * (option selector must be 1, other values reserved) | |
1115 | */ | |
1116 | ||
1117 | static int | |
1118 | sysctl_trigger_kernel_coredump(struct sysctl_oid *oidp __unused, void *arg1, int arg2, struct sysctl_req *req) | |
1119 | { | |
1120 | int error = 0; | |
1121 | hvg_hcall_return_t hv_ret; | |
1122 | char buf[2]; // 1 digit for dump option + 1 '\0' | |
1123 | ||
1124 | if (req->newptr) { | |
1125 | // Write request | |
1126 | if (req->newlen > 1) { | |
1127 | return EINVAL; | |
1128 | } | |
1129 | error = SYSCTL_IN(req, buf, req->newlen); | |
1130 | buf[req->newlen] = '\0'; | |
1131 | if (!error) { | |
1132 | if (strcmp(buf, "1") != 0) { | |
1133 | return EINVAL; | |
1134 | } | |
1135 | /* Issue hypercall to trigger a dump */ | |
1136 | hv_ret = hvg_hcall_trigger_dump(arg1, HVG_HCALL_DUMP_OPTION_REGULAR); | |
1137 | ||
1138 | /* Translate hypercall error code to syscall error code */ | |
1139 | switch (hv_ret) { | |
1140 | case HVG_HCALL_SUCCESS: | |
1141 | error = SYSCTL_OUT(req, arg1, 41); | |
1142 | break; | |
1143 | case HVG_HCALL_ACCESS_DENIED: | |
1144 | error = EPERM; | |
1145 | break; | |
1146 | case HVG_HCALL_INVALID_CODE: | |
1147 | case HVG_HCALL_INVALID_PARAMETER: | |
1148 | error = EINVAL; | |
1149 | break; | |
1150 | case HVG_HCALL_IO_FAILED: | |
1151 | error = EIO; | |
1152 | break; | |
1153 | case HVG_HCALL_FEAT_DISABLED: | |
1154 | case HVG_HCALL_UNSUPPORTED: | |
1155 | error = ENOTSUP; | |
1156 | break; | |
1157 | default: | |
1158 | error = ENODEV; | |
1159 | } | |
1160 | } | |
1161 | } else { | |
1162 | // Read request | |
1163 | error = SYSCTL_OUT(req, arg1, arg2); | |
1164 | } | |
1165 | return error; | |
1166 | } | |
1167 | ||
1168 | ||
1169 | static hvg_hcall_vmcore_file_t sysctl_vmcore; | |
1170 | ||
1171 | void | |
1172 | hvg_bsd_init(void) | |
1173 | { | |
1174 | if (!cpuid_vmm_present()) { | |
1175 | return; | |
1176 | } | |
1177 | ||
1178 | if ((cpuid_vmm_get_applepv_features() & CPUID_LEAF_FEATURE_COREDUMP) != 0) { | |
1179 | /* Register an OID in the sysctl MIB tree for kern.trigger_kernel_coredump */ | |
1180 | struct sysctl_oid *hcall_trigger_dump_oid = zalloc_permanent(sizeof(struct sysctl_oid), ZALIGN(struct sysctl_oid)); | |
1181 | struct sysctl_oid oid = SYSCTL_STRUCT_INIT(_kern, | |
1182 | OID_AUTO, | |
1183 | trigger_kernel_coredump, | |
1184 | CTLTYPE_STRING | CTLFLAG_RW, | |
1185 | &sysctl_vmcore, sizeof(sysctl_vmcore), | |
1186 | sysctl_trigger_kernel_coredump, | |
1187 | "A", "Request that the hypervisor take a live kernel dump"); | |
1188 | *hcall_trigger_dump_oid = oid; | |
1189 | sysctl_register_oid(hcall_trigger_dump_oid); | |
1190 | } | |
1191 | } | |
1192 | ||
39037602 | 1193 | #endif /* DEVELOPMENT || DEBUG */ |