diff -urN /usr/src/sys/dev/msr/msr.c src/sys/dev/msr/msr.c --- /usr/src/sys/dev/msr/msr.c Thu Jan 1 01:00:00 1970 +++ src/sys/dev/msr/msr.c Fri May 26 16:12:50 2006 @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2006 Suleiman Souhlal + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static d_read_t msr_read; +static d_write_t msr_write; + +static struct cdevsw msr_cdevsw = { + .d_version = D_VERSION, + .d_read = msr_read, + .d_write = msr_write, + .d_name = "msr", +}; + +/* For use with make_dev(9)/destroy_dev(9). */ +static struct cdev *msr_dev[MAXCPU]; + +/* ARGSUSED */ +static int +msr_read(struct cdev *dev, struct uio *uio, int flag) +{ + int cpu, error = 0; + long long msr; + + cpu = minor(dev); + + mtx_lock_spin(&sched_lock); + sched_bind(curthread, cpu); + mtx_unlock_spin(&sched_lock); + + while (uio->uio_resid > 0) { + msr = rdmsr(uio->uio_offset); + if ((error = uiomove(&msr, sizeof(msr), uio)) != 0) + break; + + } + mtx_lock_spin(&sched_lock); + sched_unbind(curthread); + mtx_unlock_spin(&sched_lock); + + return (error); +} + +/* ARGSUSED */ +static int +msr_write(struct cdev *dev __unused, struct uio *uio, int flag __unused) +{ + int cpu, error = 0; + long long value; + long msr; + + cpu = minor(dev); + + mtx_lock_spin(&sched_lock); + sched_bind(curthread, cpu); + mtx_unlock_spin(&sched_lock); + + while (uio->uio_resid > 0) { + msr = uio->uio_offset; + error = uiomove(&value, sizeof(value), uio); + if (error) + break; + wrmsr(msr, value); + } + + mtx_lock_spin(&sched_lock); + sched_unbind(curthread); + mtx_unlock_spin(&sched_lock); + + return (error); +} + +extern int smp_cpus; + +/* ARGSUSED */ +static int +msr_modevent(module_t mod __unused, int type, void *data __unused) +{ + int i, error = 0; + char name[512]; + + switch (type) { + case MOD_LOAD: + for (i = 0; i < smp_cpus; i++) { + snprintf(name, 512, "cpu%dmsr", i); + msr_dev[i] = make_dev(&msr_cdevsw, i, + UID_ROOT, GID_WHEEL, 0666, name); + } + break; + + case MOD_UNLOAD: + for (i = 0; i < smp_cpus; i++) + destroy_dev(msr_dev[i]); + + break; + + case MOD_SHUTDOWN: + break; + + default: + error = EOPNOTSUPP; + break; + + } + return (error); +} + +DEV_MODULE(msr, msr_modevent, NULL); +MODULE_VERSION(msr, 1); diff -urN /usr/src/sys/dev/msr/rdmsr.c src/sys/dev/msr/rdmsr.c --- /usr/src/sys/dev/msr/rdmsr.c Thu Jan 1 01:00:00 1970 +++ src/sys/dev/msr/rdmsr.c Thu May 25 09:00:02 2006 @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + int fd, cpu; + long msr, buf, error; + char path[512]; + + if (argc < 3) { + printf("usage: %s \n", argv[0]); + return (1); + } + + msr = strtol(argv[2], NULL, 16); + cpu = strtoimax(argv[1], NULL, 10); + printf("msr %lx\n", msr); + + snprintf(path, 512, "/dev/cpu%dmsr", cpu); + if ((fd = open(path, O_RDONLY)) < 0) { + perror("open"); + return (1); + } + error = lseek(fd, msr, SEEK_SET); + printf("lseek %ld\n", error); + + if (lseek(fd, msr, SEEK_SET) < 0) { + perror("lseek"); + return (1); + } + if (read(fd, &buf, sizeof(buf)) < sizeof(buf)) { + perror("read"); + return (1); + } + printf("msr %lx = %lx\n", msr, buf); + + return (0); +} diff -urN /usr/src/sys/dev/msr/wrmsr.c src/sys/dev/msr/wrmsr.c --- /usr/src/sys/dev/msr/wrmsr.c Thu Jan 1 01:00:00 1970 +++ src/sys/dev/msr/wrmsr.c Fri May 26 16:14:38 2006 @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + int fd, error, cpu; + long msr, val; + char path[512]; + + if (argc < 4) { + printf("usage: %s \n", argv[0]); + return (1); + } + + msr = strtol(argv[2], NULL, 16); + val = strtol(argv[3], NULL, 16); + cpu = strtoimax(argv[0], NULL, 10); + + snprintf(path, 512, "/dev/cpu%dmsr", cpu); + printf("cpu %d msr %lx value %lx path %s\n", cpu, msr, val, path); + if ((fd = open(path, O_RDWR)) < 0) { + perror("open"); + return (1); + } + if (lseek(fd, msr, SEEK_SET) < 0) { + perror("lseek"); + return (1); + } + error = write(fd, &val, sizeof(val)); + if (error < sizeof(val)) { + perror("write"); + return (1); + } + printf("msr %lx = %lx\n", msr, val); + + return (0); +} diff -urN /usr/src/sys/modules/msr/Makefile src/sys/modules/msr/Makefile --- /usr/src/sys/modules/msr/Makefile Thu Jan 1 01:00:00 1970 +++ src/sys/modules/msr/Makefile Thu May 25 07:35:52 2006 @@ -0,0 +1,10 @@ +# $FreeBSD: src/sys/modules/random/Makefile,v 1.15 2004/04/11 15:40:18 marcel Exp $ + +.PATH: ${.CURDIR}/../../dev/msr + +KMOD= msr +SRCS= msr.c + +CFLAGS+= -I${.CURDIR}/../.. + +.include