1/*
2 * Copyright (c) 2003-2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <string.h>
30#include <sys/param.h>
31#include <sys/kernel.h>
32#include <sys/sysctl.h>
33#include <i386/cpuid.h>
34#include <i386/tsc.h>
35#include <i386/machine_routines.h>
36#include <i386/pal_routines.h>
37#include <i386/ucode.h>
38#include <kern/clock.h>
39#include <libkern/libkern.h>
40#include <i386/lapic.h>
41
42
43static int
44_i386_cpu_info SYSCTL_HANDLER_ARGS
45{
46    __unused struct sysctl_oid *unused_oidp = oidp;
47    void *ptr = arg1;
48    int value;
49
50    if (arg2 == -1) {
51        ptr = *(void **)ptr;
52        arg2 = 0;
53    }
54
55    if (arg2 == 0 && ((char *)ptr)[0] == '\0') {
56        return ENOENT;
57    }
58
59    if (arg2 == sizeof(uint8_t)) {
60	value = (uint32_t) *(uint8_t *)ptr;
61	ptr = &value;
62	arg2 = sizeof(uint32_t);
63    }
64    return SYSCTL_OUT(req, ptr, arg2 ? (size_t) arg2 : strlen((char *)ptr)+1);
65}
66
67static int
68i386_cpu_info SYSCTL_HANDLER_ARGS
69{
70    void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1;
71    return _i386_cpu_info(oidp, ptr, arg2, req);
72}
73
74static int
75i386_cpu_info_nonzero SYSCTL_HANDLER_ARGS
76{
77    void *ptr = (uint8_t *)cpuid_info() + (uintptr_t)arg1;
78    int value = *(uint32_t *)ptr;
79
80    if (value == 0)
81        return ENOENT;
82
83    return _i386_cpu_info(oidp, ptr, arg2, req);
84}
85static int
86cpu_mwait SYSCTL_HANDLER_ARGS
87{
88    i386_cpu_info_t *cpu_info = cpuid_info();
89    void *ptr = (uint8_t *)cpu_info->cpuid_mwait_leafp + (uintptr_t)arg1;
90    if (cpu_info->cpuid_mwait_leafp == NULL)
91        return ENOENT;
92    return _i386_cpu_info(oidp, ptr, arg2, req);
93}
94
95static int
96cpu_thermal SYSCTL_HANDLER_ARGS
97{
98    i386_cpu_info_t *cpu_info = cpuid_info();
99    void *ptr = (uint8_t *)cpu_info->cpuid_thermal_leafp + (uintptr_t)arg1;
100    if (cpu_info->cpuid_thermal_leafp == NULL)
101        return ENOENT;
102    return _i386_cpu_info(oidp, ptr, arg2, req);
103}
104
105static int
106cpu_arch_perf SYSCTL_HANDLER_ARGS
107{
108    i386_cpu_info_t *cpu_info = cpuid_info();
109    void *ptr = (uint8_t *)cpu_info->cpuid_arch_perf_leafp + (uintptr_t)arg1;
110    if (cpu_info->cpuid_arch_perf_leafp == NULL)
111        return ENOENT;
112    return _i386_cpu_info(oidp, ptr, arg2, req);
113}
114
115static int
116cpu_xsave SYSCTL_HANDLER_ARGS
117{
118    i386_cpu_info_t *cpu_info = cpuid_info();
119    void *ptr = (uint8_t *)cpu_info->cpuid_xsave_leafp + (uintptr_t)arg1;
120    if (cpu_info->cpuid_xsave_leafp == NULL)
121        return ENOENT;
122    return _i386_cpu_info(oidp, ptr, arg2, req);
123}
124
125
126static int
127cpu_features SYSCTL_HANDLER_ARGS
128{
129    __unused struct sysctl_oid *unused_oidp = oidp;
130    __unused void *unused_arg1 = arg1;
131    __unused int unused_arg2 = arg2;
132    char buf[512];
133
134    buf[0] = '\0';
135    cpuid_get_feature_names(cpuid_features(), buf, sizeof(buf));
136
137    return SYSCTL_OUT(req, buf, strlen(buf) + 1);
138}
139
140static int
141cpu_extfeatures SYSCTL_HANDLER_ARGS
142{
143    __unused struct sysctl_oid *unused_oidp = oidp;
144    __unused void *unused_arg1 = arg1;
145    __unused int unused_arg2 = arg2;
146    char buf[512];
147
148    buf[0] = '\0';
149    cpuid_get_extfeature_names(cpuid_extfeatures(), buf, sizeof(buf));
150
151    return SYSCTL_OUT(req, buf, strlen(buf) + 1);
152}
153
154static int
155cpu_leaf7_features SYSCTL_HANDLER_ARGS
156{
157    __unused struct sysctl_oid *unused_oidp = oidp;
158    __unused void *unused_arg1 = arg1;
159    __unused int unused_arg2 = arg2;
160    char buf[512];
161
162    uint32_t	leaf7_features = cpuid_info()->cpuid_leaf7_features;
163    if (leaf7_features == 0)
164        return ENOENT;
165
166    buf[0] = '\0';
167    cpuid_get_leaf7_feature_names(leaf7_features, buf, sizeof(buf));
168
169    return SYSCTL_OUT(req, buf, strlen(buf) + 1);
170}
171
172static int
173cpu_logical_per_package SYSCTL_HANDLER_ARGS
174{
175	__unused struct sysctl_oid *unused_oidp = oidp;
176	__unused void *unused_arg1 = arg1;
177	__unused int unused_arg2 = arg2;
178	i386_cpu_info_t *cpu_info = cpuid_info();
179
180	if (!(cpuid_features() & CPUID_FEATURE_HTT))
181		return ENOENT;
182
183	return SYSCTL_OUT(req, &cpu_info->cpuid_logical_per_package,
184			  sizeof(cpu_info->cpuid_logical_per_package));
185}
186
187static int
188cpu_flex_ratio_desired SYSCTL_HANDLER_ARGS
189{
190	__unused struct sysctl_oid *unused_oidp = oidp;
191	__unused void *unused_arg1 = arg1;
192	__unused int unused_arg2 = arg2;
193	i386_cpu_info_t *cpu_info = cpuid_info();
194
195	if (cpu_info->cpuid_model != 26)
196		return ENOENT;
197
198	return SYSCTL_OUT(req, &flex_ratio, sizeof(flex_ratio));
199}
200
201static int
202cpu_flex_ratio_min SYSCTL_HANDLER_ARGS
203{
204	__unused struct sysctl_oid *unused_oidp = oidp;
205	__unused void *unused_arg1 = arg1;
206	__unused int unused_arg2 = arg2;
207	i386_cpu_info_t *cpu_info = cpuid_info();
208
209	if (cpu_info->cpuid_model != 26)
210		return ENOENT;
211
212	return SYSCTL_OUT(req, &flex_ratio_min, sizeof(flex_ratio_min));
213}
214
215static int
216cpu_flex_ratio_max SYSCTL_HANDLER_ARGS
217{
218	__unused struct sysctl_oid *unused_oidp = oidp;
219	__unused void *unused_arg1 = arg1;
220	__unused int unused_arg2 = arg2;
221	i386_cpu_info_t *cpu_info = cpuid_info();
222
223	if (cpu_info->cpuid_model != 26)
224		return ENOENT;
225
226	return SYSCTL_OUT(req, &flex_ratio_max, sizeof(flex_ratio_max));
227}
228
229static int
230cpu_ucode_update SYSCTL_HANDLER_ARGS
231{
232	__unused struct sysctl_oid *unused_oidp = oidp;
233	__unused void *unused_arg1 = arg1;
234	__unused int unused_arg2 = arg2;
235	uint64_t addr;
236	int error;
237
238	error = SYSCTL_IN(req, &addr, sizeof(addr));
239	if (error)
240		return error;
241
242	int ret = ucode_interface(addr);
243	return ret;
244}
245
246extern uint64_t panic_restart_timeout;
247static int
248panic_set_restart_timeout(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
249{
250	int new_value = 0, old_value = 0, changed = 0, error;
251	uint64_t nstime;
252
253	if (panic_restart_timeout) {
254		absolutetime_to_nanoseconds(panic_restart_timeout, &nstime);
255		old_value = nstime / NSEC_PER_SEC;
256	}
257
258	error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
259	if (error == 0 && changed) {
260		nanoseconds_to_absolutetime(((uint64_t)new_value) * NSEC_PER_SEC, &panic_restart_timeout);
261	}
262	return error;
263}
264
265/*
266 * Populates the {CPU, vector, latency} triple for the maximum observed primary
267 * interrupt latency
268 */
269static int
270misc_interrupt_latency_max(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
271{
272	int changed = 0, error;
273	char buf[128];
274	buf[0] = '\0';
275
276	interrupt_populate_latency_stats(buf, sizeof(buf));
277
278	error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed);
279
280	if (error == 0 && changed) {
281		interrupt_reset_latency_stats();
282	}
283
284	return error;
285}
286
287/*
288 * Triggers a machine-check exception - for a suitably configured kernel only.
289 */
290extern void mca_exception_panic(void);
291static int
292misc_machine_check_panic(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
293{
294	int changed = 0, error;
295	char buf[128];
296	buf[0] = '\0';
297
298	error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed);
299
300	if (error == 0 && changed) {
301		mca_exception_panic();
302	}
303	return error;
304}
305
306
307SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
308	"CPU info");
309
310SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_basic, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
311	    (void *)offsetof(i386_cpu_info_t, cpuid_max_basic),sizeof(uint32_t),
312	    i386_cpu_info, "IU", "Max Basic Information value");
313
314SYSCTL_PROC(_machdep_cpu, OID_AUTO, max_ext, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
315	    (void *)offsetof(i386_cpu_info_t, cpuid_max_ext), sizeof(uint32_t),
316	    i386_cpu_info, "IU", "Max Extended Function Information value");
317
318SYSCTL_PROC(_machdep_cpu, OID_AUTO, vendor, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
319	    (void *)offsetof(i386_cpu_info_t, cpuid_vendor), 0,
320	    i386_cpu_info, "A", "CPU vendor");
321
322SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand_string, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
323	    (void *)offsetof(i386_cpu_info_t, cpuid_brand_string), 0,
324	    i386_cpu_info, "A", "CPU brand string");
325
326SYSCTL_PROC(_machdep_cpu, OID_AUTO, family, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
327	    (void *)offsetof(i386_cpu_info_t, cpuid_family), sizeof(uint8_t),
328	    i386_cpu_info, "I", "CPU family");
329
330SYSCTL_PROC(_machdep_cpu, OID_AUTO, model, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
331	    (void *)offsetof(i386_cpu_info_t, cpuid_model), sizeof(uint8_t),
332	    i386_cpu_info, "I", "CPU model");
333
334SYSCTL_PROC(_machdep_cpu, OID_AUTO, extmodel, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
335	    (void *)offsetof(i386_cpu_info_t, cpuid_extmodel), sizeof(uint8_t),
336	    i386_cpu_info, "I", "CPU extended model");
337
338SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfamily, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
339	    (void *)offsetof(i386_cpu_info_t, cpuid_extfamily), sizeof(uint8_t),
340	    i386_cpu_info, "I", "CPU extended family");
341
342SYSCTL_PROC(_machdep_cpu, OID_AUTO, stepping, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
343	    (void *)offsetof(i386_cpu_info_t, cpuid_stepping), sizeof(uint8_t),
344	    i386_cpu_info, "I", "CPU stepping");
345
346SYSCTL_PROC(_machdep_cpu, OID_AUTO, feature_bits, CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
347	    (void *)offsetof(i386_cpu_info_t, cpuid_features), sizeof(uint64_t),
348	    i386_cpu_info, "IU", "CPU features");
349
350SYSCTL_PROC(_machdep_cpu, OID_AUTO, leaf7_feature_bits,
351	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
352	    (void *)offsetof(i386_cpu_info_t, cpuid_leaf7_features),
353	    sizeof(uint32_t),
354	    i386_cpu_info_nonzero, "IU", "CPU Leaf7 features");
355
356SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeature_bits, CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
357	    (void *)offsetof(i386_cpu_info_t, cpuid_extfeatures), sizeof(uint64_t),
358	    i386_cpu_info, "IU", "CPU extended features");
359
360SYSCTL_PROC(_machdep_cpu, OID_AUTO, signature, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
361	    (void *)offsetof(i386_cpu_info_t, cpuid_signature), sizeof(uint32_t),
362	    i386_cpu_info, "I", "CPU signature");
363
364SYSCTL_PROC(_machdep_cpu, OID_AUTO, brand, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
365	    (void *)offsetof(i386_cpu_info_t, cpuid_brand), sizeof(uint8_t),
366	    i386_cpu_info, "I", "CPU brand");
367
368SYSCTL_PROC(_machdep_cpu, OID_AUTO, features, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
369	    0, 0,
370	    cpu_features, "A", "CPU feature names");
371
372SYSCTL_PROC(_machdep_cpu, OID_AUTO, leaf7_features,
373	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
374	    0, 0,
375	    cpu_leaf7_features, "A", "CPU Leaf7 feature names");
376
377SYSCTL_PROC(_machdep_cpu, OID_AUTO, extfeatures, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED,
378	    0, 0,
379	    cpu_extfeatures, "A", "CPU extended feature names");
380
381SYSCTL_PROC(_machdep_cpu, OID_AUTO, logical_per_package,
382	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
383	    0, 0,
384	    cpu_logical_per_package, "I", "CPU logical cpus per package");
385
386SYSCTL_PROC(_machdep_cpu, OID_AUTO, cores_per_package,
387	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
388	    (void *)offsetof(i386_cpu_info_t, cpuid_cores_per_package),
389	    sizeof(uint32_t),
390	    i386_cpu_info, "I", "CPU cores per package");
391
392SYSCTL_PROC(_machdep_cpu, OID_AUTO, microcode_version,
393	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
394	    (void *)offsetof(i386_cpu_info_t, cpuid_microcode_version),
395	    sizeof(uint32_t),
396	    i386_cpu_info, "I", "Microcode version number");
397
398SYSCTL_PROC(_machdep_cpu, OID_AUTO, processor_flag,
399	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
400	    (void *)offsetof(i386_cpu_info_t, cpuid_processor_flag),
401	    sizeof(uint32_t),
402	    i386_cpu_info, "I", "CPU processor flag");
403
404
405SYSCTL_NODE(_machdep_cpu, OID_AUTO, mwait, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
406	"mwait");
407
408SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_min,
409	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
410	    (void *)offsetof(cpuid_mwait_leaf_t, linesize_min),
411	    sizeof(uint32_t),
412	    cpu_mwait, "I", "Monitor/mwait minimum line size");
413
414SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, linesize_max,
415	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
416	    (void *)offsetof(cpuid_mwait_leaf_t, linesize_max),
417	    sizeof(uint32_t),
418	    cpu_mwait, "I", "Monitor/mwait maximum line size");
419
420SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, extensions,
421	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
422	    (void *)offsetof(cpuid_mwait_leaf_t, extensions),
423	    sizeof(uint32_t),
424	    cpu_mwait, "I", "Monitor/mwait extensions");
425
426SYSCTL_PROC(_machdep_cpu_mwait, OID_AUTO, sub_Cstates,
427	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
428	    (void *)offsetof(cpuid_mwait_leaf_t, sub_Cstates),
429	    sizeof(uint32_t),
430	    cpu_mwait, "I", "Monitor/mwait sub C-states");
431
432
433SYSCTL_NODE(_machdep_cpu, OID_AUTO, thermal, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
434	"thermal");
435
436SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, sensor,
437	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
438	    (void *)offsetof(cpuid_thermal_leaf_t, sensor),
439	    sizeof(boolean_t),
440	    cpu_thermal, "I", "Thermal sensor present");
441
442SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, dynamic_acceleration,
443	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
444	    (void *)offsetof(cpuid_thermal_leaf_t, dynamic_acceleration),
445	    sizeof(boolean_t),
446	    cpu_thermal, "I", "Dynamic Acceleration Technology (Turbo Mode)");
447
448SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, invariant_APIC_timer,
449	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
450	    (void *)offsetof(cpuid_thermal_leaf_t, invariant_APIC_timer),
451	    sizeof(boolean_t),
452	    cpu_thermal, "I", "Invariant APIC Timer");
453
454SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, thresholds,
455	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
456	    (void *)offsetof(cpuid_thermal_leaf_t, thresholds),
457	    sizeof(uint32_t),
458	    cpu_thermal, "I", "Number of interrupt thresholds");
459
460SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, ACNT_MCNT,
461	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
462	    (void *)offsetof(cpuid_thermal_leaf_t, ACNT_MCNT),
463	    sizeof(boolean_t),
464	    cpu_thermal, "I", "ACNT_MCNT capability");
465
466SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, core_power_limits,
467	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
468	    (void *)offsetof(cpuid_thermal_leaf_t, core_power_limits),
469	    sizeof(boolean_t),
470	    cpu_thermal, "I", "Power Limit Notifications at a Core Level");
471
472SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, fine_grain_clock_mod,
473	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
474	    (void *)offsetof(cpuid_thermal_leaf_t, fine_grain_clock_mod),
475	    sizeof(boolean_t),
476	    cpu_thermal, "I", "Fine Grain Clock Modulation");
477
478SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, package_thermal_intr,
479	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
480	    (void *)offsetof(cpuid_thermal_leaf_t, package_thermal_intr),
481	    sizeof(boolean_t),
482	    cpu_thermal, "I", "Package Thermal interrupt and Status");
483
484SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, hardware_feedback,
485	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
486	    (void *)offsetof(cpuid_thermal_leaf_t, hardware_feedback),
487	    sizeof(boolean_t),
488	    cpu_thermal, "I", "Hardware Coordination Feedback");
489
490SYSCTL_PROC(_machdep_cpu_thermal, OID_AUTO, energy_policy,
491	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
492	    (void *)offsetof(cpuid_thermal_leaf_t, energy_policy),
493	    sizeof(boolean_t),
494	    cpu_thermal, "I", "Energy Efficient Policy Support");
495
496SYSCTL_NODE(_machdep_cpu, OID_AUTO, xsave, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
497	"xsave");
498
499SYSCTL_PROC(_machdep_cpu_xsave, OID_AUTO, extended_state,
500	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
501	    (void *)offsetof(cpuid_xsave_leaf_t, extended_state),
502	    sizeof(cpuid_xsave_leaf_t),
503	    cpu_xsave, "IU", "XSAVE Extended State");
504
505
506SYSCTL_NODE(_machdep_cpu, OID_AUTO, arch_perf, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
507	"arch_perf");
508
509SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, version,
510	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
511	    (void *)offsetof(cpuid_arch_perf_leaf_t, version),
512	    sizeof(uint8_t),
513	    cpu_arch_perf, "I", "Architectural Performance Version Number");
514
515SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, number,
516	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
517	    (void *)offsetof(cpuid_arch_perf_leaf_t, number),
518	    sizeof(uint8_t),
519	    cpu_arch_perf, "I", "Number of counters per logical cpu");
520
521SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, width,
522	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
523	    (void *)offsetof(cpuid_arch_perf_leaf_t, width),
524	    sizeof(uint8_t),
525	    cpu_arch_perf, "I", "Bit width of counters");
526
527SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events_number,
528	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
529	    (void *)offsetof(cpuid_arch_perf_leaf_t, events_number),
530	    sizeof(uint8_t),
531	    cpu_arch_perf, "I", "Number of monitoring events");
532
533SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, events,
534	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
535	    (void *)offsetof(cpuid_arch_perf_leaf_t, events),
536	    sizeof(uint32_t),
537	    cpu_arch_perf, "I", "Bit vector of events");
538
539SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_number,
540	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
541	    (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_number),
542	    sizeof(uint8_t),
543	    cpu_arch_perf, "I", "Number of fixed-function counters");
544
545SYSCTL_PROC(_machdep_cpu_arch_perf, OID_AUTO, fixed_width,
546	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
547	    (void *)offsetof(cpuid_arch_perf_leaf_t, fixed_width),
548	    sizeof(uint8_t),
549	    cpu_arch_perf, "I", "Bit-width of fixed-function counters");
550
551
552SYSCTL_NODE(_machdep_cpu, OID_AUTO, cache, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
553	"cache");
554
555SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, linesize,
556	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
557	    (void *)offsetof(i386_cpu_info_t, cpuid_cache_linesize),
558	    sizeof(uint32_t),
559	    i386_cpu_info, "I", "Cacheline size");
560
561SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, L2_associativity,
562	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
563	    (void *)offsetof(i386_cpu_info_t, cpuid_cache_L2_associativity),
564	    sizeof(uint32_t),
565	    i386_cpu_info, "I", "L2 cache associativity");
566
567SYSCTL_PROC(_machdep_cpu_cache, OID_AUTO, size,
568	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
569	    (void *)offsetof(i386_cpu_info_t, cpuid_cache_size),
570	    sizeof(uint32_t),
571	    i386_cpu_info, "I", "Cache size (in Kbytes)");
572
573
574SYSCTL_NODE(_machdep_cpu, OID_AUTO, tlb, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
575	"tlb");
576SYSCTL_NODE(_machdep_cpu_tlb, OID_AUTO, inst, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
577	"inst");
578SYSCTL_NODE(_machdep_cpu_tlb, OID_AUTO, data, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
579	"data");
580
581SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, small,
582	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
583	    (void *)offsetof(i386_cpu_info_t,
584			     cpuid_tlb[TLB_INST][TLB_SMALL][0]),
585	    sizeof(uint32_t),
586	    i386_cpu_info_nonzero, "I",
587	    "Number of small page instruction TLBs");
588
589SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small,
590	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
591	    (void *)offsetof(i386_cpu_info_t,
592			     cpuid_tlb[TLB_DATA][TLB_SMALL][0]),
593	    sizeof(uint32_t),
594	    i386_cpu_info_nonzero, "I",
595	    "Number of small page data TLBs (1st level)");
596
597SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, small_level1,
598	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
599	    (void *)offsetof(i386_cpu_info_t,
600			     cpuid_tlb[TLB_DATA][TLB_SMALL][1]),
601	    sizeof(uint32_t),
602	    i386_cpu_info_nonzero, "I",
603	    "Number of small page data TLBs (2nd level)");
604
605SYSCTL_PROC(_machdep_cpu_tlb_inst, OID_AUTO, large,
606	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
607	    (void *)offsetof(i386_cpu_info_t,
608			     cpuid_tlb[TLB_INST][TLB_LARGE][0]),
609	    sizeof(uint32_t),
610	    i386_cpu_info_nonzero, "I",
611	    "Number of large page instruction TLBs");
612
613SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large,
614	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
615	    (void *)offsetof(i386_cpu_info_t,
616			     cpuid_tlb[TLB_DATA][TLB_LARGE][0]),
617	    sizeof(uint32_t),
618	    i386_cpu_info_nonzero, "I",
619	    "Number of large page data TLBs (1st level)");
620
621SYSCTL_PROC(_machdep_cpu_tlb_data, OID_AUTO, large_level1,
622	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
623	    (void *)offsetof(i386_cpu_info_t,
624			     cpuid_tlb[TLB_DATA][TLB_LARGE][1]),
625	    sizeof(uint32_t),
626	    i386_cpu_info_nonzero, "I",
627	    "Number of large page data TLBs (2nd level)");
628
629SYSCTL_PROC(_machdep_cpu_tlb, OID_AUTO, shared,
630	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
631	    (void *)offsetof(i386_cpu_info_t, cpuid_stlb),
632	    sizeof(uint32_t),
633	    i386_cpu_info_nonzero, "I",
634	    "Number of shared TLBs");
635
636
637SYSCTL_NODE(_machdep_cpu, OID_AUTO, address_bits, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
638	"address_bits");
639
640SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, physical,
641	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
642	    (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_physical),
643	    sizeof(uint32_t),
644	    i386_cpu_info, "I", "Number of physical address bits");
645
646SYSCTL_PROC(_machdep_cpu_address_bits, OID_AUTO, virtual,
647	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
648	    (void *)offsetof(i386_cpu_info_t, cpuid_address_bits_virtual),
649	    sizeof(uint32_t),
650	    i386_cpu_info, "I", "Number of virtual address bits");
651
652
653SYSCTL_PROC(_machdep_cpu, OID_AUTO, core_count,
654	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
655	    (void *)offsetof(i386_cpu_info_t, core_count),
656	    sizeof(uint32_t),
657	    i386_cpu_info, "I", "Number of enabled cores per package");
658
659SYSCTL_PROC(_machdep_cpu, OID_AUTO, thread_count,
660	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
661	    (void *)offsetof(i386_cpu_info_t, thread_count),
662	    sizeof(uint32_t),
663	    i386_cpu_info, "I", "Number of enabled threads per package");
664
665SYSCTL_NODE(_machdep_cpu, OID_AUTO, flex_ratio, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
666	"Flex ratio");
667
668SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, desired,
669	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
670	    0, 0,
671	    cpu_flex_ratio_desired, "I", "Flex ratio desired (0 disabled)");
672
673SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, min,
674	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
675	    0, 0,
676	    cpu_flex_ratio_min, "I", "Flex ratio min (efficiency)");
677
678SYSCTL_PROC(_machdep_cpu_flex_ratio, OID_AUTO, max,
679	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED,
680	    0, 0,
681	    cpu_flex_ratio_max, "I", "Flex ratio max (non-turbo)");
682
683SYSCTL_PROC(_machdep_cpu, OID_AUTO, ucupdate,
684			CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_LOCKED, 0, 0,
685            cpu_ucode_update, "S", "Microcode update interface");
686
687static const uint32_t apic_timer_vector = (LAPIC_DEFAULT_INTERRUPT_BASE + LAPIC_TIMER_INTERRUPT);
688static const uint32_t apic_IPI_vector = (LAPIC_DEFAULT_INTERRUPT_BASE + LAPIC_INTERPROCESSOR_INTERRUPT);
689
690SYSCTL_NODE(_machdep, OID_AUTO, vectors, CTLFLAG_RD | CTLFLAG_LOCKED, 0,
691	"Interrupt vector assignments");
692
693SYSCTL_UINT     (_machdep_vectors, OID_AUTO, timer, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, (uint32_t *)&apic_timer_vector, 0, "");
694SYSCTL_UINT     (_machdep_vectors, OID_AUTO, IPI, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, (uint32_t *)&apic_IPI_vector, 0, "");
695
696uint64_t pmap_pv_hashlist_walks;
697uint64_t pmap_pv_hashlist_cnts;
698uint32_t pmap_pv_hashlist_max;
699uint32_t pmap_kernel_text_ps = PAGE_SIZE;
700extern uint32_t pv_hashed_kern_low_water_mark;
701
702/*extern struct sysctl_oid_list sysctl__machdep_pmap_children;*/
703
704SYSCTL_NODE(_machdep, OID_AUTO, pmap, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
705	"PMAP info");
706
707SYSCTL_QUAD    (_machdep_pmap, OID_AUTO, hashwalks, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_walks, "");
708SYSCTL_QUAD    (_machdep_pmap, OID_AUTO, hashcnts, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_cnts, "");
709SYSCTL_INT     (_machdep_pmap, OID_AUTO, hashmax, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_pv_hashlist_max, 0, "");
710SYSCTL_INT     (_machdep_pmap, OID_AUTO, kernel_text_ps, CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, &pmap_kernel_text_ps, 0, "");
711SYSCTL_INT     (_machdep_pmap, OID_AUTO, kern_pv_reserve, CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, &pv_hashed_kern_low_water_mark, 0, "");
712
713SYSCTL_NODE(_machdep, OID_AUTO, memmap, CTLFLAG_RD|CTLFLAG_LOCKED, NULL, "physical memory map");
714
715uint64_t firmware_Conventional_bytes = 0;
716uint64_t firmware_RuntimeServices_bytes = 0;
717uint64_t firmware_ACPIReclaim_bytes = 0;
718uint64_t firmware_ACPINVS_bytes = 0;
719uint64_t firmware_PalCode_bytes = 0;
720uint64_t firmware_Reserved_bytes = 0;
721uint64_t firmware_Unusable_bytes = 0;
722uint64_t firmware_other_bytes = 0;
723
724SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Conventional, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_Conventional_bytes, "");
725SYSCTL_QUAD(_machdep_memmap, OID_AUTO, RuntimeServices, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_RuntimeServices_bytes, "");
726SYSCTL_QUAD(_machdep_memmap, OID_AUTO, ACPIReclaim, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_ACPIReclaim_bytes, "");
727SYSCTL_QUAD(_machdep_memmap, OID_AUTO, ACPINVS, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_ACPINVS_bytes, "");
728SYSCTL_QUAD(_machdep_memmap, OID_AUTO, PalCode, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_PalCode_bytes, "");
729SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Reserved, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_Reserved_bytes, "");
730SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Unusable, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_Unusable_bytes, "");
731SYSCTL_QUAD(_machdep_memmap, OID_AUTO, Other, CTLFLAG_RD|CTLFLAG_LOCKED, &firmware_other_bytes, "");
732
733SYSCTL_NODE(_machdep, OID_AUTO, tsc, CTLFLAG_RD|CTLFLAG_LOCKED, NULL, "Timestamp counter parameters");
734
735SYSCTL_QUAD(_machdep_tsc, OID_AUTO, frequency,
736	CTLFLAG_RD|CTLFLAG_LOCKED, &tscFreq, "");
737
738extern uint32_t deep_idle_rebase;
739SYSCTL_UINT(_machdep_tsc, OID_AUTO, deep_idle_rebase,
740	CTLFLAG_RW|CTLFLAG_KERN|CTLFLAG_LOCKED, &deep_idle_rebase, 0, "");
741
742SYSCTL_NODE(_machdep_tsc, OID_AUTO, nanotime,
743	CTLFLAG_RD|CTLFLAG_LOCKED, NULL, "TSC to ns conversion");
744SYSCTL_QUAD(_machdep_tsc_nanotime, OID_AUTO, tsc_base,
745	CTLFLAG_RD | CTLFLAG_LOCKED,
746	(uint64_t *) &pal_rtc_nanotime_info.tsc_base, "");
747SYSCTL_QUAD(_machdep_tsc_nanotime, OID_AUTO, ns_base,
748	CTLFLAG_RD | CTLFLAG_LOCKED,
749	(uint64_t *)&pal_rtc_nanotime_info.ns_base, "");
750SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, scale,
751	CTLFLAG_RD | CTLFLAG_LOCKED,
752	(uint32_t *)&pal_rtc_nanotime_info.scale, 0, "");
753SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, shift,
754	CTLFLAG_RD | CTLFLAG_LOCKED,
755	(uint32_t *)&pal_rtc_nanotime_info.shift, 0, "");
756SYSCTL_UINT(_machdep_tsc_nanotime, OID_AUTO, generation,
757	CTLFLAG_RD | CTLFLAG_LOCKED,
758	(uint32_t *)&pal_rtc_nanotime_info.generation, 0, "");
759
760SYSCTL_NODE(_machdep, OID_AUTO, misc, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
761	"Miscellaneous x86 kernel parameters");
762
763SYSCTL_PROC(_machdep_misc, OID_AUTO, panic_restart_timeout,
764	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
765	    0, 0,
766	    panic_set_restart_timeout, "I", "Panic restart timeout in seconds");
767
768SYSCTL_PROC(_machdep_misc, OID_AUTO, interrupt_latency_max,
769	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
770	    0, 0,
771	    misc_interrupt_latency_max, "A", "Maximum Interrupt latency");
772
773SYSCTL_PROC(_machdep_misc, OID_AUTO, machine_check_panic,
774	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
775	    0, 0,
776	    misc_machine_check_panic, "A", "Machine-check exception test");
777
778
779
780extern void timer_queue_trace_cpu(int);
781static int
782misc_timer_queue_trace(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
783{
784	int changed = 0, error;
785	char buf[128];
786	buf[0] = '\0';
787
788	error = sysctl_io_string(req, buf, sizeof(buf), 0, &changed);
789
790	if (error == 0 && changed) {
791		timer_queue_trace_cpu(0);
792	}
793	return error;
794}
795
796SYSCTL_PROC(_machdep_misc, OID_AUTO, timer_queue_trace,
797	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED,
798	    0, 0,
799	    misc_timer_queue_trace, "A", "Cut timer queue tracepoint");
800
801extern long NMI_count;
802extern void NMI_cpus(void);
803static int
804misc_nmis(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
805{
806	int new = 0, old = 0, changed = 0, error;
807
808	old = NMI_count;
809
810	error = sysctl_io_number(req, old, sizeof(int), &new, &changed);
811	if (error == 0 && changed) {
812		NMI_cpus();
813	}
814
815	return error;
816}
817
818SYSCTL_PROC(_machdep_misc, OID_AUTO, nmis,
819	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
820	    0, 0,
821	    misc_nmis, "I", "Report/increment NMI count");
822
823/* Parameters related to timer coalescing tuning, to be replaced
824 * with a dedicated systemcall in the future.
825 */
826/* Enable processing pending timers in the context of any other interrupt */
827SYSCTL_INT(_kern, OID_AUTO, interrupt_timer_coalescing_enabled,
828		CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
829		&interrupt_timer_coalescing_enabled, 0, "");
830/* Upon entering idle, process pending timers with HW deadlines
831 * this far in the future.
832 */
833SYSCTL_INT(_kern, OID_AUTO, timer_coalesce_idle_entry_hard_deadline_max,
834		CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
835		&idle_entry_timer_processing_hdeadline_threshold, 0, "");
836
837/* Track potentially expensive eager timer evaluations on QoS tier
838 * switches.
839 */
840extern uint32_t ml_timer_eager_evaluations;
841
842SYSCTL_INT(_machdep, OID_AUTO, eager_timer_evaluations,
843		CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
844		&ml_timer_eager_evaluations, 0, "");
845
846extern uint64_t ml_timer_eager_evaluation_max;
847
848SYSCTL_QUAD(_machdep, OID_AUTO, eager_timer_evaluation_max,
849		CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED,
850		&ml_timer_eager_evaluation_max, "");
851