Annotation of src/sys/arch/x86/x86/procfs_machdep.c, Revision 1.15.2.13
1.15.2.13! martin 1: /* $NetBSD: procfs_machdep.c,v 1.15.2.12 2021/12/03 19:53:32 martin Exp $ */
1.1 rmind 2:
3: /*
4: * Copyright (c) 2001 Wasabi Systems, Inc.
5: * All rights reserved.
6: *
7: * Written by Frank van der Linden and Jason R. Thorpe for
8: * Wasabi Systems, Inc.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed for the NetBSD Project by
21: * Wasabi Systems, Inc.
22: * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23: * or promote products derived from this software without specific prior
24: * written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: /*
40: * NOTE: We simply use the primary CPU's cpuid_level and tsc_freq
41: * here. Might want to change this later.
42: */
43:
44: #include <sys/cdefs.h>
1.15.2.13! martin 45: __KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.15.2.12 2021/12/03 19:53:32 martin Exp $");
1.1 rmind 46:
47: #include <sys/param.h>
48: #include <sys/systm.h>
49: #include <sys/mount.h>
50: #include <sys/stat.h>
51: #include <sys/vnode.h>
52:
53: #include <miscfs/procfs/procfs.h>
54:
55: #include <machine/cpu.h>
56: #include <machine/reg.h>
57: #include <machine/specialreg.h>
1.15.2.2 martin 58: #include <x86/cputypes.h>
59: #include <x86/cpuvar.h>
1.1 rmind 60:
1.10 msaitoh 61: /*
1.11 msaitoh 62: * The feature table. The order is the same as Linux's
1.10 msaitoh 63: * x86/include/asm/cpufeatures.h.
64: */
1.8 msaitoh 65: static const char * const x86_features[][32] = {
1.13 msaitoh 66: { /* (0) Common: 0x0000001 edx */
1.1 rmind 67: "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
68: "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
69: "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
1.8 msaitoh 70: "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"},
71:
1.13 msaitoh 72: { /* (1) AMD-defined: 0x80000001 edx */
1.8 msaitoh 73: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
74: NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
75: NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
76: NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext","3dnow"},
77:
1.10 msaitoh 78: { /* (2) Transmeta-defined */
1.8 msaitoh 79: "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
80: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
81: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
82: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
83:
1.10 msaitoh 84: { /* (3) Linux mapping */
1.15.2.12 martin 85: "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL,
86: "constant_tsc", "up", "art", "arch_perfmon",
87: "pebs", "bts", NULL, NULL,
88: "rep_good", NULL, NULL, "acc_power",
89: "nopl", NULL, "xtopology", "tsc_reliable",
90: "nonstop_tsc", "cpuid", "extd_apicid", "amd_dcm",
91: "aperfmperf", "rapl", "nonstop_tsc_s3", "tsc_known_freq"},
1.8 msaitoh 92:
1.13 msaitoh 93: { /* (4) Intel-defined: 0x00000001 ecx */
1.8 msaitoh 94: "pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est",
95: "tm2", "ssse3", "cid", "sdbg", "fma", "cx16", "xtpr", "pdcm",
96: NULL, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt",
97: "tsc_deadline_timer", "aes", "xsave", NULL,
98: "avx", "f16c", "rdrand", "hypervisor"},
99:
100: { /* (5) VIA/Cyrix/Centaur-defined */
101: NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
1.13 msaitoh 102: "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
1.8 msaitoh 103: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
104: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
105:
106: { /* (6) AMD defined 80000001 ecx */
107: "lahf_lm", "cmp_legacy", "svm", "extapic",
108: "cr8_legacy", "abm", "sse4a", "misalignsse",
109: "3dnowprefetch", "osvw", "ibs", "xop", "skinit", "wdt", NULL, "lwp",
110: "fma4", "tce", NULL, "nodeid_msr",
111: NULL, "tbm", "topoext", "perfctr_core",
1.12 msaitoh 112: "perfctr_nb", NULL, "bpext", "ptsc",
1.15.2.2 martin 113: "perfctr_llc", "mwaitx", NULL, NULL},
1.8 msaitoh 114:
1.10 msaitoh 115: { /* (7) Linux mapping */
1.12 msaitoh 116: NULL, NULL, "cpb", "ebp", NULL, "pln", "pts", "dtherm",
1.15.2.12 martin 117: "hw_pstate", "proc_feedback", NULL, NULL,
1.15.2.3 snj 118: NULL, NULL, NULL, NULL,
1.8 msaitoh 119: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1.15.2.8 martin 120: NULL, "ibrs", "ibpb", "stibp", NULL, NULL, NULL, NULL},
1.8 msaitoh 121:
122: { /* (8) Linux mapping */
1.15.2.13! martin 123: "tpr_shadow", "vnmi", "flexpriority", "ept", "vpid", NULL, NULL, NULL,
! 124: NULL, NULL, NULL, NULL, NULL, NULL, NULL, "vmmcall",
1.15.2.8 martin 125: NULL, "ept_ad", NULL, NULL, NULL, NULL, NULL, NULL,
1.8 msaitoh 126: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
127:
128: { /* (9) Intel-defined: 00000007 ebx */
1.15.2.12 martin 129: "fsgsbase", "tsc_adjust", "sgx", "bmi1", "hle", "avx2", NULL, "smep",
1.14 msaitoh 130: "bmi2", "erms", "invpcid", "rtm", "cqm", NULL, "mpx", "rdt_a",
1.12 msaitoh 131: "avx512f", "avx512dq", "rdseed", "adx",
1.15.2.10 martin 132: "smap", "avx512ifma", NULL, "clflushopt",
1.15.2.3 snj 133: "clwb", "intel_pt", "avx512pf", "avx512er",
1.12 msaitoh 134: "avx512cd", "sha_ni", "avx512bw", "avx512vl"},
1.8 msaitoh 135:
1.15.2.2 martin 136: { /* (10) 0x0000000d:1 eax */
1.8 msaitoh 137: "xsaveopt", "xsavec", "xgetbv1", "xsaves", NULL, NULL, NULL, NULL,
138: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
140: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
141:
1.15.2.13! martin 142: { /* (11) Linux mapping */
! 143: "cqm_llc", "cqm_occup_llc", "cqm_mbm_total", "cqm_mbm_local",
! 144: NULL, NULL, "split_lock_detect", NULL,
1.8 msaitoh 145: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
146: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
147: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
148:
1.15.2.13! martin 149: { /* (12) Intel-defined 0x00000007:1 eax */
1.15.2.10 martin 150: NULL, NULL, NULL, NULL,
1.15.2.13! martin 151: "avx_vnni", "avx512_bf16", NULL, NULL,
1.8 msaitoh 152: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
153: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
154: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1.15 msaitoh 155:
1.15.2.4 martin 156: { /* (13) AMD 0x80000008 ebx */
1.15.2.10 martin 157: "clzero", "irperf", "xsaveerptr", NULL, "rdpru", NULL, NULL, NULL,
1.15.2.8 martin 158: NULL, "wbnoinvd", NULL, NULL, NULL, NULL, NULL, NULL,
1.15.2.11 martin 159: NULL, NULL, NULL, NULL, NULL, NULL, NULL, "ppin",
1.15.2.13! martin 160: NULL, "virt_ssbd", NULL, "cppc", NULL, NULL, NULL, NULL},
1.15 msaitoh 161:
162: { /* (14) 0x00000006 eax */
163: "dtherm", "ida", "arat", NULL, "pln", NULL, "pts", "hwp",
164: "hwp_notify", "hwp_act_window", "hwp_epp","hwp_pkg_req",
165: NULL, NULL, NULL, NULL,
166: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
167: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
168:
1.15.2.12 martin 169: { /* (15) AMD 0x8000000a edx */
1.15 msaitoh 170: "npt", "lbrv", "svm_lock", "nrip_save",
171: "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
1.15.2.2 martin 172: NULL, NULL, "pausefilter", NULL, "pfthreshold", "avic", NULL,
173: "v_vmsave_vmload",
1.15.2.12 martin 174: "vgif", NULL, NULL, NULL, "v_spec_ctrl", NULL, NULL, NULL,
1.15 msaitoh 175: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
176:
177: { /* (16) 0x00000007:0 ecx */
1.15.2.4 martin 178: NULL, "avx512vbmi", "umip", "pku",
1.15.2.10 martin 179: "ospke", "waitpkg", "avx512_vbmi2", NULL,
1.15.2.4 martin 180: "gfni", "vaes", "vpclmulqdq", "avx512_vnni",
1.15.2.8 martin 181: "avx512_bitalg", "tme", "avx512_vpopcntdq", NULL,
1.15 msaitoh 182: "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL,
1.15.2.13! martin 183: NULL, "cldemote", NULL, "movdiri",
! 184: "movdir64b", "enqcmd", "sgx_lc", NULL},
1.15 msaitoh 185:
186: { /* (17) 0x80000007 ebx */
1.15.2.2 martin 187: "overflow_recov", "succor", NULL, "smca", NULL, NULL, NULL, NULL,
1.15 msaitoh 188: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
189: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
190: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1.15.2.4 martin 191:
192: { /* (18) Intel 0x00000007 edx */
1.15.2.10 martin 193: NULL, NULL, "avx512_4vnniw", "avx512_4fmaps", "fsrm", NULL, NULL, NULL,
1.15.2.12 martin 194: "vp2intersect", NULL, "md_clear", NULL, NULL, NULL, "serialize", NULL,
1.15.2.13! martin 195: "tsxldtrk", NULL, "pconfig", "arch_lbr",
! 196: NULL, NULL, NULL, "avx512_fp16",
1.15.2.6 martin 197: NULL, NULL, NULL, NULL,
198: "flush_l1d", "arch_capabilities", NULL, "ssbd"},
1.15.2.12 martin 199:
200: { /* (19) AMD 0x8000001f eax */
201: "sme", "sev", NULL, "sev_es", NULL, NULL, NULL, NULL,
202: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
203: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
204: NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
1.1 rmind 205: };
206:
1.6 christos 207: static int procfs_getonecpu(int, struct cpu_info *, char *, size_t *);
1.1 rmind 208:
209: /*
210: * Linux-style /proc/cpuinfo.
211: * Only used when procfs is mounted with -o linux.
212: *
213: * In the multiprocessor case, this should be a loop over all CPUs.
214: */
215: int
1.6 christos 216: procfs_getcpuinfstr(char *bf, size_t *len)
1.1 rmind 217: {
218: struct cpu_info *ci;
219: CPU_INFO_ITERATOR cii;
1.6 christos 220: size_t i, total, size, used;
1.1 rmind 221:
1.6 christos 222: i = total = 0;
223: used = size = *len;
1.8 msaitoh 224:
1.1 rmind 225: for (CPU_INFO_FOREACH(cii, ci)) {
1.6 christos 226: procfs_getonecpu(i++, ci, bf, &used);
227: total += used + 1;
1.15.2.1 martin 228: if (used + 1 <= size) {
1.1 rmind 229: bf += used;
230: *bf++ = '\n';
1.6 christos 231: size -= used + 1;
232: used = size;
233: } else
234: used = 0;
1.1 rmind 235: }
1.6 christos 236: size = *len;
237: *len = total;
238: return size < *len ? -1 : 0;
1.1 rmind 239: }
240:
241: static int
1.8 msaitoh 242: procfs_getonefeatreg(uint32_t reg, const char * const *table, char *p,
243: size_t *left)
244: {
245: size_t l;
246:
247: for (size_t i = 0; i < 32; i++) {
1.15.2.10 martin 248: if ((reg & (1U << i)) && table[i]) {
1.8 msaitoh 249: l = snprintf(p, *left, "%s ", table[i]);
250: if (l < *left) {
251: *left -= l;
252: p += l;
253: } else
254: break;
255: }
256: }
257:
258: return 0; /* XXX */
259: }
260:
261: /*
1.10 msaitoh 262: * Print feature bits. The code assume that unused entry of x86_features[]
1.8 msaitoh 263: * is zero-cleared.
264: *
265: * XXX This function will be rewritten when all of linux entries are
266: * decoded.
267: */
268: static int
269: procfs_getonecpufeatures(struct cpu_info *ci, char *p, size_t *left)
270: {
271: size_t last = *left;
272: size_t diff;
1.15.2.2 martin 273: u_int descs[4];
1.8 msaitoh 274:
275: procfs_getonefeatreg(ci->ci_feat_val[0], x86_features[0], p, left);
276: diff = last - *left;
277:
278: procfs_getonefeatreg(ci->ci_feat_val[2], x86_features[1], p + diff,
279: left);
280: diff = last - *left;
281:
282: /* x86_features[2] is for Transmeta */
283: /* x86_features[3] is Linux defined mapping */
1.15.2.12 martin 284:
1.8 msaitoh 285: procfs_getonefeatreg(ci->ci_feat_val[1], x86_features[4], p + diff,
286: left);
287: diff = last - *left;
288:
289: procfs_getonefeatreg(ci->ci_feat_val[4], x86_features[5], p + diff,
290: left);
291: diff = last - *left;
292:
293: procfs_getonefeatreg(ci->ci_feat_val[3], x86_features[6], p + diff,
294: left);
295: diff = last - *left;
296:
297: /* x86_features[7] is Linux defined mapping */
298: /* x86_features[8] is Linux defined mapping */
299:
300: procfs_getonefeatreg(ci->ci_feat_val[5], x86_features[9], p + diff,
301: left);
302: diff = last - *left;
303:
1.15.2.2 martin 304: if (ci->ci_max_cpuid >= 0x0d) {
305: x86_cpuid2(0x0d, 1, descs);
306: procfs_getonefeatreg(descs[0], x86_features[10], p + diff,
307: left);
308: diff = last - *left;
309: }
310:
1.15.2.13! martin 311: /* x86_features[11] is Linux defined mapping */
1.15.2.2 martin 312:
1.15.2.13! martin 313: if (ci->ci_max_cpuid >= 0x07) {
! 314: x86_cpuid2(0x07, 1, descs);
! 315: procfs_getonefeatreg(descs[0], x86_features[12], p + diff,
1.15.2.2 martin 316: left);
317: diff = last - *left;
318: }
319:
320: if ((cpu_vendor == CPUVENDOR_AMD)
321: && (ci->ci_max_ext_cpuid >= 0x80000008)) {
322: x86_cpuid(0x80000008, descs);
323: procfs_getonefeatreg(descs[1], x86_features[13], p + diff,
324: left);
325: diff = last - *left;
326: }
327:
328: if (ci->ci_max_cpuid >= 0x06) {
329: x86_cpuid(0x06, descs);
330: procfs_getonefeatreg(descs[0], x86_features[14], p + diff,
331: left);
332: diff = last - *left;
333: }
334:
335: if ((cpu_vendor == CPUVENDOR_AMD)
336: && (ci->ci_max_ext_cpuid >= 0x8000000a)) {
337: x86_cpuid(0x8000000a, descs);
338: procfs_getonefeatreg(descs[3], x86_features[15], p + diff,
339: left);
340: diff = last - *left;
341: }
1.15 msaitoh 342:
343: procfs_getonefeatreg(ci->ci_feat_val[6], x86_features[16], p + diff,
344: left);
345: diff = last - *left;
346:
1.15.2.2 martin 347: if ((cpu_vendor == CPUVENDOR_AMD)
348: && (ci->ci_max_ext_cpuid >= 0x80000007)) {
349: x86_cpuid(0x80000007, descs);
350: procfs_getonefeatreg(descs[1], x86_features[17], p + diff,
351: left);
352: diff = last - *left;
353: }
1.10 msaitoh 354:
1.15.2.4 martin 355: if ((cpu_vendor == CPUVENDOR_INTEL)
356: && (ci->ci_max_cpuid >= 0x00000007)) {
357: x86_cpuid(0x00000007, descs);
358: procfs_getonefeatreg(descs[3], x86_features[18], p + diff,
359: left);
360: diff = last - *left;
361: }
362:
1.15.2.12 martin 363: if ((cpu_vendor == CPUVENDOR_AMD)
364: && (ci->ci_max_ext_cpuid >= 0x80000019)) {
365: x86_cpuid(0x8000001f, descs);
366: procfs_getonefeatreg(descs[0], x86_features[19], p + diff,
367: left);
368: diff = last - *left;
369: }
370:
1.8 msaitoh 371: return 0; /* XXX */
372: }
373:
374: static int
1.6 christos 375: procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, size_t *len)
1.1 rmind 376: {
1.6 christos 377: size_t left, l, size;
378: char featurebuf[1024], *p;
1.1 rmind 379:
380: p = featurebuf;
381: left = sizeof(featurebuf);
1.6 christos 382: size = *len;
1.8 msaitoh 383: procfs_getonecpufeatures(ci, p, &left);
1.1 rmind 384:
385: p = bf;
386: left = *len;
1.6 christos 387: size = 0;
1.1 rmind 388: l = snprintf(p, left,
389: "processor\t: %d\n"
390: "vendor_id\t: %s\n"
391: "cpu family\t: %d\n"
392: "model\t\t: %d\n"
393: "model name\t: %s\n"
394: "stepping\t: ",
395: xcpu,
396: (char *)ci->ci_vendor,
1.9 msaitoh 397: CPUID_TO_FAMILY(ci->ci_signature),
398: CPUID_TO_MODEL(ci->ci_signature),
1.1 rmind 399: cpu_brand_string
400: );
1.6 christos 401: size += l;
402: if (l < left) {
403: left -= l;
404: p += l;
405: } else
406: left = 0;
1.1 rmind 407:
408: if (cpuid_level >= 0)
1.9 msaitoh 409: l = snprintf(p, left, "%d\n",
410: CPUID_TO_STEPPING(ci->ci_signature));
1.1 rmind 411: else
412: l = snprintf(p, left, "unknown\n");
413:
1.6 christos 414: size += l;
415: if (l < left) {
416: left -= l;
417: p += l;
418: } else
419: left = 0;
1.1 rmind 420:
421: if (ci->ci_data.cpu_cc_freq != 0) {
422: uint64_t freq, fraq;
423:
424: freq = (ci->ci_data.cpu_cc_freq + 4999) / 1000000;
425: fraq = ((ci->ci_data.cpu_cc_freq + 4999) / 10000) % 100;
1.8 msaitoh 426: l = snprintf(p, left, "cpu MHz\t\t: %" PRIu64 ".%02" PRIu64
427: "\n", freq, fraq);
1.1 rmind 428: } else
429: l = snprintf(p, left, "cpu MHz\t\t: unknown\n");
430:
1.6 christos 431: size += l;
432: if (l < left) {
433: left -= l;
434: p += l;
435: } else
436: left = 0;
1.1 rmind 437:
438: l = snprintf(p, left,
1.15.2.7 martin 439: "apicid\t\t: %lu\n"
440: "initial apicid\t: %u\n",
441: ci->ci_cpuid,
1.15 msaitoh 442: ci->ci_initapicid
443: );
444: size += l;
445: if (l < left) {
446: left -= l;
447: p += l;
448: } else
449: left = 0;
450:
451: l = snprintf(p, left,
452: #ifdef __i386__
1.1 rmind 453: "fdiv_bug\t: %s\n"
1.15 msaitoh 454: #endif
1.1 rmind 455: "fpu\t\t: %s\n"
1.2 dsl 456: "fpu_exception\t: yes\n"
1.1 rmind 457: "cpuid level\t: %d\n"
458: "wp\t\t: %s\n"
1.15 msaitoh 459: "flags\t\t: %s\n"
460: "clflush size\t: %d\n",
461: #ifdef __i386__
1.3 dsl 462: i386_fpu_fdivbug ? "yes" : "no", /* an old pentium */
1.15 msaitoh 463: #endif
1.3 dsl 464: i386_fpu_present ? "yes" : "no", /* not a 486SX */
1.15.2.2 martin 465: ci->ci_max_cpuid,
1.1 rmind 466: (rcr0() & CR0_WP) ? "yes" : "no",
1.15 msaitoh 467: featurebuf,
468: ci->ci_cflush_lsize
1.1 rmind 469: );
1.6 christos 470: size += l;
1.1 rmind 471:
1.6 christos 472: left = *len;
473: *len = size;
474: return left < *len ? -1 : 0;
1.1 rmind 475: }
476:
477: #if defined(__HAVE_PROCFS_MACHDEP) && !defined(__x86_64__)
478:
479: void
480: procfs_machdep_allocvp(struct vnode *vp)
481: {
482: struct pfsnode *pfs = vp->v_data;
483:
484: switch (pfs->pfs_type) {
485: case Pmachdep_xmmregs:
486: /* /proc/N/xmmregs = -rw------- */
487: pfs->pfs_mode = S_IRUSR|S_IWUSR;
488: vp->v_type = VREG;
489: break;
490: default:
491: KASSERT(false);
492: }
493: }
494:
495: int
496: procfs_machdep_rw(struct lwp *curl, struct lwp *l, struct pfsnode *pfs,
497: struct uio *uio)
498: {
499:
500: switch (pfs->pfs_type) {
501: case Pmachdep_xmmregs:
502: return (procfs_machdep_doxmmregs(curl, l, pfs, uio));
503: default:
504: KASSERT(false);
505: }
506: return EINVAL;
507: }
508:
509: int
510: procfs_machdep_getattr(struct vnode *vp, struct vattr *vap, struct proc *procp)
511: {
512: struct pfsnode *pfs = VTOPFS(vp);
513:
514: switch (pfs->pfs_type) {
515: case Pmachdep_xmmregs:
516: vap->va_bytes = vap->va_size = sizeof(struct xmmregs);
517: break;
518: default:
519: KASSERT(false);
520: }
521: return 0;
522: }
523:
524: int
525: procfs_machdep_doxmmregs(struct lwp *curl, struct lwp *l,
526: struct pfsnode *pfs, struct uio *uio)
527: {
528:
529: return process_machdep_doxmmregs(curl, l, uio);
530: }
531:
532: int
533: procfs_machdep_validxmmregs(struct lwp *l, struct mount *mp)
534: {
535:
536: return process_machdep_validxmmregs(l->l_proc);
537: }
538:
539: #endif
CVSweb <webmaster@jp.NetBSD.org>