[BACK]Return to procfs_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / x86

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>