Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / i386 / i386 / procfs_machdep.c
blobeed40f3e67c38b5515e7bb464260de56d27d77cd
1 /* $NetBSD: procfs_machdep.c,v 1.31 2008/06/11 21:47:46 njoly Exp $ */
3 /*
4 * Copyright (c) 2001 Wasabi Systems, Inc.
5 * All rights reserved.
7 * Written by Frank van der Linden and Jason R. Thorpe for
8 * Wasabi Systems, Inc.
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.
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>
50 #include <sys/stat.h>
51 #include <sys/vnode.h>
52 #include <sys/proc.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.
78 int
79 procfs_getcpuinfstr(char *bf, int *len)
81 struct cpu_info *ci;
82 CPU_INFO_ITERATOR cii;
83 int i = 0, used = *len, total = *len;
85 *len = 0;
86 for (CPU_INFO_FOREACH(cii, ci)) {
87 if (procfs_getonecpu(i++, ci, bf, &used) == 0) {
88 *len += used;
89 total = 0;
90 break;
92 total -= used;
93 if (total > 0) {
94 bf += used;
95 *bf++ = '\n';
96 *len += used + 1;
97 used = --total;
98 if (used == 0)
99 break;
100 } else {
101 *len += used;
102 break;
105 return total == 0 ? -1 : 0;
108 static int
109 procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, int *len)
111 int left, l, i;
112 char featurebuf[256], *p;
114 p = featurebuf;
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]);
119 left -= l;
120 p += l;
121 if (left <= 0)
122 break;
126 p = bf;
127 left = *len;
128 l = snprintf(p, left,
129 "processor\t: %d\n"
130 "vendor_id\t: %s\n"
131 "cpu family\t: %d\n"
132 "model\t\t: %d\n"
133 "model name\t: %s\n"
134 "stepping\t: ",
135 xcpu,
136 (char *)ci->ci_vendor,
137 cpuid_level >= 0 ?
138 ((ci->ci_signature >> 8) & 15) : cpu_class + 3,
139 cpuid_level >= 0 ?
140 ((ci->ci_signature >> 4) & 15) : 0,
141 cpu_brand_string
144 left -= l;
145 p += l;
146 if (left <= 0)
147 return 0;
149 if (cpuid_level >= 0)
150 l = snprintf(p, left, "%d\n", ci->ci_signature & 15);
151 else
152 l = snprintf(p, left, "unknown\n");
154 left -= l;
155 p += l;
156 if (left <= 0)
157 return 0;
160 if (ci->ci_data.cpu_cc_freq != 0) {
161 uint64_t freq, fraq;
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",
166 freq, fraq);
167 } else
168 l = snprintf(p, left, "cpu MHz\t\t: unknown\n");
170 left -= l;
171 p += l;
172 if (left <= 0)
173 return 0;
175 l = snprintf(p, left,
176 "fdiv_bug\t: %s\n"
177 "fpu\t\t: %s\n"
178 "fpu_exception\t: %s\n"
179 "cpuid level\t: %d\n"
180 "wp\t\t: %s\n"
181 "flags\t\t: %s\n",
182 i386_fpu_fdivbug ? "yes" : "no",
183 i386_fpu_present ? "yes" : "no",
184 i386_fpu_exception ? "yes" : "no",
185 cpuid_level,
186 (rcr0() & CR0_WP) ? "yes" : "no",
187 featurebuf);
189 if (l > left)
190 return 0;
191 *len = (p + l) - bf;
193 return 1;
196 #ifdef __HAVE_PROCFS_MACHDEP
197 void
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;
205 vp->v_type = VREG;
206 break;
208 default:
209 panic("procfs_machdep_allocvp");
214 procfs_machdep_rw(struct lwp *curl, struct lwp *l, struct pfsnode *pfs,
215 struct uio *uio)
218 switch (pfs->pfs_type) {
219 case Pmachdep_xmmregs:
220 return (procfs_machdep_doxmmregs(curl, l, pfs, uio));
222 default:
223 panic("procfs_machdep_rw");
226 /* NOTREACHED */
227 return (EINVAL);
231 procfs_machdep_getattr(struct vnode *vp, struct vattr *vap,
232 struct proc *procp)
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);
239 break;
241 default:
242 panic("procfs_machdep_getattr");
245 return (0);
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));
262 #endif