Please review the following patch that adds FreeBSD support to msrtool. MSR values are obtained via /dev/cpuctl ioctl interface. Signed-off-by: Andriy Gapon avg@icyb.net.ua
Index: msrtool.c =================================================================== --- msrtool.c (revision 4776) +++ msrtool.c (working copy) @@ -49,6 +49,7 @@ static struct sysdef allsystems[] = { { "linux", "Linux with /dev/cpu/*/msr", linux_probe, linux_open, linux_close, linux_rdmsr }, { "darwin", "OS X with DirectIO", darwin_probe, darwin_open, darwin_close, darwin_rdmsr }, + { "freebsd", "FreeBSD with /dev/cpuctl*", freebsd_probe, freebsd_open, freebsd_close, freebsd_rdmsr }, { SYSTEM_EOT } };
Index: Makefile.in =================================================================== --- Makefile.in (revision 4776) +++ Makefile.in (working copy) @@ -27,7 +27,7 @@ LDFLAGS = @LDFLAGS@
TARGETS = geodelx.o cs5536.o k8.o -SYSTEMS = linux.o darwin.o +SYSTEMS = linux.o darwin.o freebsd.o OBJS = $(PROGRAM).o msrutils.o sys.o $(SYSTEMS) $(TARGETS)
all: $(PROGRAM) Index: msrtool.h =================================================================== --- msrtool.h (revision 4776) +++ msrtool.h (working copy) @@ -28,6 +28,10 @@ #define __DARWIN__ #include <DirectIO/darwinio.h> #endif +#if defined(__FreeBSD__) +#include <sys/ioctl.h> +#include <sys/cpuctl.h> +#endif #include <pci/pci.h>
#define HEXCHARS "0123456789abcdefABCDEF" @@ -186,6 +190,12 @@ extern int darwin_close(uint8_t cpu); extern int darwin_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val);
+/* freebsd.c */ +extern int freebsd_probe(const struct sysdef *system); +extern int freebsd_open(uint8_t cpu, enum SysModes mode); +extern int freebsd_close(uint8_t cpu); +extern int freebsd_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val); + /** target externs **/
/* geodelx.c */ Index: freebsd.c =================================================================== --- freebsd.c (revision 0) +++ freebsd.c (revision 0) @@ -0,0 +1,96 @@ +/* + * This file is part of msrtool. + * + * Copyright (c) 2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include "msrtool.h" + +static int msr_fd[MAX_CORES] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +int freebsd_probe(const struct sysdef *system) +{ +#ifdef __FreeBSD__ + struct stat st; + + return stat("/dev/cpuctl0", &st) == 0; +#else + return 0; +#endif +} + +int freebsd_open(uint8_t cpu, enum SysModes mode) +{ +#ifdef __FreeBSD__ + char devname[32]; + + if (cpu >= MAX_CORES) + return 0; + + snprintf(devname, sizeof(devname), "/dev/cpuctl%u", cpu); + msr_fd[cpu] = open(devname, O_RDONLY); + if (msr_fd[cpu] < 0) { + perror(devname); + return 0; + } + return 1; +#else + return 0; +#endif +} + +int freebsd_close(uint8_t cpu) +{ + if (cpu >= MAX_CORES) + return 0; + + if (msr_fd[cpu] != -1) + close(msr_fd[cpu]); + msr_fd[cpu] = -1; + return 1; +} + +int freebsd_rdmsr(uint8_t cpu, uint32_t addr, struct msr *val) +{ +#ifdef __FreeBSD__ + cpuctl_msr_args_t args; + + if (cpu >= MAX_CORES) + return 0; + + if (msr_fd[cpu] < 0) + return 0; + + args.msr = addr; + if (ioctl(msr_fd[cpu], CPUCTL_RDMSR, &args) < 0) { + perror("CPUCTL_RDMSR"); + return 0; + } + + val->hi = args.data >> 32; + val->lo = args.data & 0xffffffff; + return 1; +#else + return 0; +#endif +}