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