1 /* $NetBSD: procfs_machdep.c,v 1.31 2008/06/11 21:47:46 njoly Exp $ */
4 * Copyright (c) 2001 Wasabi Systems, Inc.
7 * Written by Frank van der Linden and Jason R. Thorpe for
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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
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.
40 * NOTE: We simply use the primary CPU's cpuid_level and tsc_freq
41 * here. Might want to change this later.
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.31 2008/06/11 21:47:46 njoly Exp $");
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/mount.h>
51 #include <sys/vnode.h>
54 #include <miscfs/procfs/procfs.h>
56 #include <machine/cpu.h>
57 #include <machine/reg.h>
58 #include <machine/specialreg.h>
60 extern int i386_fpu_present
, i386_fpu_exception
, i386_fpu_fdivbug
;
61 extern char cpu_model
[];
63 static const char * const i386_features
[] = {
64 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
65 "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
66 "pat", "pse36", "pn", "clflush", "20", "dts", "acpi", "mmx",
67 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "31"
70 static int procfs_getonecpu(int, struct cpu_info
*, char *, int *);
73 * Linux-style /proc/cpuinfo.
74 * Only used when procfs is mounted with -o linux.
76 * In the multiprocessor case, this should be a loop over all CPUs.
79 procfs_getcpuinfstr(char *bf
, int *len
)
82 CPU_INFO_ITERATOR cii
;
83 int i
= 0, used
= *len
, total
= *len
;
86 for (CPU_INFO_FOREACH(cii
, ci
)) {
87 if (procfs_getonecpu(i
++, ci
, bf
, &used
) == 0) {
105 return total
== 0 ? -1 : 0;
109 procfs_getonecpu(int xcpu
, struct cpu_info
*ci
, char *bf
, int *len
)
112 char featurebuf
[256], *p
;
115 left
= sizeof featurebuf
;
116 for (i
= 0; i
< 32; i
++) {
117 if (ci
->ci_feature_flags
& (1 << i
)) {
118 l
= snprintf(p
, left
, "%s ", i386_features
[i
]);
128 l
= snprintf(p
, left
,
136 (char *)ci
->ci_vendor
,
138 ((ci
->ci_signature
>> 8) & 15) : cpu_class
+ 3,
140 ((ci
->ci_signature
>> 4) & 15) : 0,
149 if (cpuid_level
>= 0)
150 l
= snprintf(p
, left
, "%d\n", ci
->ci_signature
& 15);
152 l
= snprintf(p
, left
, "unknown\n");
160 if (ci
->ci_data
.cpu_cc_freq
!= 0) {
163 freq
= (ci
->ci_data
.cpu_cc_freq
+ 4999) / 1000000;
164 fraq
= ((ci
->ci_data
.cpu_cc_freq
+ 4999) / 10000) % 100;
165 l
= snprintf(p
, left
, "cpu MHz\t\t: %" PRIu64
".%" PRIu64
"\n",
168 l
= snprintf(p
, left
, "cpu MHz\t\t: unknown\n");
175 l
= snprintf(p
, left
,
178 "fpu_exception\t: %s\n"
179 "cpuid level\t: %d\n"
182 i386_fpu_fdivbug
? "yes" : "no",
183 i386_fpu_present
? "yes" : "no",
184 i386_fpu_exception
? "yes" : "no",
186 (rcr0() & CR0_WP
) ? "yes" : "no",
196 #ifdef __HAVE_PROCFS_MACHDEP
198 procfs_machdep_allocvp(struct vnode
*vp
)
200 struct pfsnode
*pfs
= vp
->v_data
;
202 switch (pfs
->pfs_type
) {
203 case Pmachdep_xmmregs
: /* /proc/N/xmmregs = -rw------- */
204 pfs
->pfs_mode
= S_IRUSR
|S_IWUSR
;
209 panic("procfs_machdep_allocvp");
214 procfs_machdep_rw(struct lwp
*curl
, struct lwp
*l
, struct pfsnode
*pfs
,
218 switch (pfs
->pfs_type
) {
219 case Pmachdep_xmmregs
:
220 return (procfs_machdep_doxmmregs(curl
, l
, pfs
, uio
));
223 panic("procfs_machdep_rw");
231 procfs_machdep_getattr(struct vnode
*vp
, struct vattr
*vap
,
234 struct pfsnode
*pfs
= VTOPFS(vp
);
236 switch (pfs
->pfs_type
) {
237 case Pmachdep_xmmregs
:
238 vap
->va_bytes
= vap
->va_size
= sizeof(struct xmmregs
);
242 panic("procfs_machdep_getattr");
249 procfs_machdep_doxmmregs(struct lwp
*curl
, struct lwp
*l
,
250 struct pfsnode
*pfs
, struct uio
*uio
)
253 return (process_machdep_doxmmregs(curl
, l
, uio
));
257 procfs_machdep_validxmmregs(struct lwp
*l
, struct mount
*mp
)
260 return (process_machdep_validxmmregs(l
->l_proc
));