diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-10-17 02:30:27 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-10-17 02:30:27 +0000 |
commit | 50b7fa8fe5aa9486f8fada4e0dcbffb37eea55f2 (patch) | |
tree | 8bc086a16b979277effdafe153b6fc8d4c0d1466 /sys | |
parent | f9dca81d94e6150016691976b1ed162697e92bc2 (diff) |
replacement for the pctr codebase that can handle amd64 processors as
well (in fact, all 4 combinations of codebase and processor) written by
Mike Belopuhov and Aleksey Lomovtsev
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/pctr.c | 42 | ||||
-rw-r--r-- | sys/arch/amd64/include/pctr.h | 84 | ||||
-rw-r--r-- | sys/arch/i386/i386/pctr.c | 167 | ||||
-rw-r--r-- | sys/arch/i386/include/pctr.h | 92 | ||||
-rw-r--r-- | sys/arch/i386/include/specialreg.h | 10 |
6 files changed, 223 insertions, 176 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index e37a9b647ef..677b286a7cd 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.61 2007/08/26 18:54:37 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.62 2007/10/17 02:30:26 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -536,6 +536,8 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, newp, newlen, p); case CPU_CPUVENDOR: return (sysctl_rdstring(oldp, oldlenp, newp, cpu_vendor)); + case CPU_CPUID: + return (sysctl_rdint(oldp, oldlenp, newp, cpu_id)); case CPU_CPUFEATURE: return (sysctl_rdint(oldp, oldlenp, newp, cpu_feature)); case CPU_KBDRESET: diff --git a/sys/arch/amd64/amd64/pctr.c b/sys/arch/amd64/amd64/pctr.c index 3efe16604cb..975a9d3e6a5 100644 --- a/sys/arch/amd64/amd64/pctr.c +++ b/sys/arch/amd64/amd64/pctr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pctr.c,v 1.1 2007/09/12 18:18:27 deraadt Exp $ */ +/* $OpenBSD: pctr.c,v 1.2 2007/10/17 02:30:26 deraadt Exp $ */ /* * Copyright (c) 2007 Mike Belopuhov @@ -35,11 +35,14 @@ #include <machine/psl.h> #include <machine/pctr.h> #include <machine/cpu.h> -#include <machine/cpufunc.h> #include <machine/specialreg.h> -/* Check for Model Specific Registers and RDMSR/WRMSR support */ -#define usepctr (cpu_feature & CPUID_MSR) +#define PCTR_AMD_NUM PCTR_NUM +#define PCTR_INTEL_NUM 2 /* Intel supports only 2 counters */ + +#define usetsc (cpu_feature & CPUID_TSC) +#define usepctr ((pctr_isamd || pctr_isintel) && \ + ((cpu_id >> 8) & 15) >= 6) u_int64_t pctr_idlcnt; /* Gets incremented in locore.S */ @@ -47,6 +50,7 @@ int pctr_isamd; int pctr_isintel; static void pctrrd(struct pctrst *); +static int pctrsel(int, u_int32_t, u_int32_t); static void pctrrd(struct pctrst *st) @@ -55,20 +59,12 @@ pctrrd(struct pctrst *st) num = pctr_isamd ? PCTR_AMD_NUM : PCTR_INTEL_NUM; reg = pctr_isamd ? MSR_K7_EVNTSEL0 : MSR_EVNTSEL0; - for (i = 0; i < num; i++) st->pctr_fn[i] = rdmsr(reg + i); - - reg = pctr_isamd ? MSR_K7_PERFCTR0 : MSR_PERFCTR0; - __asm __volatile("cli"); - st->pctr_tsc = rdtsc(); - for (i = 0; i < num; i++) - st->pctr_hwc[i] = rdmsr(reg + i); - /*st->pctr_hwc[i] = rdpmc(i);*/ - + st->pctr_hwc[i] = rdpmc(i); __asm __volatile("sti"); } @@ -82,17 +78,22 @@ pctrattach(int num) pctr_isamd = (strcmp(cpu_vendor, "AuthenticAMD") == 0); if (!pctr_isamd) pctr_isintel = (strcmp(cpu_vendor, "GenuineIntel") == 0); - if (!pctr_isintel && !pctr_isamd) - return; - /* Enable RDTSC and RDPMC instructions from user-level. */ if (usepctr) { + /* Enable RDTSC and RDPMC instructions from user-level. */ __asm __volatile("movq %%cr4,%%rax\n" "\tandq %0,%%rax\n" "\torq %1,%%rax\n" "\tmovq %%rax,%%cr4" :: "i" (~CR4_TSD), "i" (CR4_PCE) : "rax"); printf("pctr: user-level performance counters enabled\n"); + } else if (usetsc) { + /* Enable RDTSC instruction from user-level. */ + __asm __volatile("movq %%cr4,%%rax\n" + "\tandq %0,%%rax\n" + "\tmovq %%rax,%%cr4" + :: "i" (~CR4_TSD) : "rax"); + printf("pctr: user-level cycle counter enabled\n"); } } @@ -112,7 +113,7 @@ pctrclose(dev_t dev, int oflags, int devtype, struct proc *p) return (0); } -int +static int pctrsel(int fflag, u_int32_t cmd, u_int32_t fn) { int msrsel, msrval; @@ -143,9 +144,8 @@ pctrsel(int fflag, u_int32_t cmd, u_int32_t fn) } int -pctrioctl(dev_t dev, u_int64_t cmd, caddr_t data, int fflag, struct proc *p) +pctrioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { - switch (cmd) { case PCIOCRD: { @@ -153,6 +153,8 @@ pctrioctl(dev_t dev, u_int64_t cmd, caddr_t data, int fflag, struct proc *p) if (usepctr) pctrrd(st); + else if (usetsc) + st->pctr_tsc = rdtsc(); st->pctr_idl = pctr_idlcnt; return (0); } @@ -161,7 +163,7 @@ pctrioctl(dev_t dev, u_int64_t cmd, caddr_t data, int fflag, struct proc *p) case PCIOCS2: case PCIOCS3: if (usepctr) - return (pctrsel(fflag, cmd, *(u_int32_t *)data)); + return (pctrsel(fflag, cmd, *(u_int *)data)); return (ENODEV); default: return (EINVAL); diff --git a/sys/arch/amd64/include/pctr.h b/sys/arch/amd64/include/pctr.h index 35c651ebffd..18e7f6fc14e 100644 --- a/sys/arch/amd64/include/pctr.h +++ b/sys/arch/amd64/include/pctr.h @@ -1,20 +1,4 @@ -/* $OpenBSD: pctr.h,v 1.1 2007/09/12 18:18:27 deraadt Exp $ */ - -/* - * Copyright (c) 2007 Mike Belopuhov - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ +/* $OpenBSD: pctr.h,v 1.2 2007/10/17 02:30:26 deraadt Exp $ */ /* * Pentium performance counter driver for OpenBSD. @@ -30,15 +14,15 @@ #include <sys/ioccom.h> +typedef u_int64_t pctrval; + #define PCTR_NUM 4 -#define PCTR_AMD_NUM PCTR_NUM -#define PCTR_INTEL_NUM 2 /* Intel supports only 2 counters */ struct pctrst { - u_int64_t pctr_hwc[PCTR_NUM]; /* Values of the hardware counters */ - u_int64_t pctr_tsc; /* Free-running 64-bit cycle counter */ - u_int64_t pctr_idl; /* Iterations of the idle loop */ - u_int32_t pctr_fn[PCTR_NUM]; /* Current settings of counters */ + u_int pctr_fn[PCTR_NUM]; /* Current settings of counters */ + pctrval pctr_tsc; /* Free-running 64-bit cycle counter */ + pctrval pctr_hwc[PCTR_NUM]; /* Values of the hardware counters */ + pctrval pctr_idl; /* Iterations of the idle loop */ }; /* Bit values in fn fields and PIOCS ioctl's */ @@ -48,16 +32,18 @@ struct pctrst { #define PCTR_EN 0x400000 /* Enable counters (counter 0 only) */ #define PCTR_I 0x800000 /* Invert counter mask */ -/* Unit Mask bits */ -#define PCTR_UM_M 0x10 /* Modified cache lines */ -#define PCTR_UM_O 0x08 /* Owned cache lines */ -#define PCTR_UM_E 0x04 /* Exclusive cache lines */ -#define PCTR_UM_S 0x02 /* Shared cache lines */ -#define PCTR_UM_I 0x01 /* Invalid cache lines */ -#define PCTR_UM_MESI (PCTR_UM_O|PCTR_UM_E|PCTR_UM_S|PCTR_UM_I) -#define PCTR_UM_MOESI (PCTR_UM_M|PCTR_UM_O|PCTR_UM_E|PCTR_UM_S|PCTR_UM_I) +/* Unit Mask values to distinguish cache coherent states */ +#define PCTR_UM_M 0x0800 /* Modified cache lines */ +#define PCTR_UM_E 0x0400 /* Exclusive cache lines */ +#define PCTR_UM_S 0x0200 /* Shared cache lines */ +#define PCTR_UM_I 0x0100 /* Invalid cache lines */ +#define PCTR_UM_MESI (PCTR_UM_M|PCTR_UM_E|PCTR_UM_S|PCTR_UM_I) +#define PCTR_UM_A 0x2000 /* Any initiator */ -/* ioctl to set which counter a device tracks. */ +#define PCTR_UM_SHIFT 8 /* Left shift for unit mask */ +#define PCTR_CM_SHIFT 24 /* Left shift for counter mask */ + +/* ioctl to set which counter a device tracks */ #define PCIOCRD _IOR('c', 1, struct pctrst) /* Read counter value */ #define PCIOCS0 _IOW('c', 8, unsigned int) /* Set counter 0 function */ #define PCIOCS1 _IOW('c', 9, unsigned int) /* Set counter 1 function */ @@ -66,13 +52,43 @@ struct pctrst { #define _PATH_PCTR "/dev/pctr" +#define rdtsc() \ +({ \ + u_int32_t hi, lo; \ + __asm __volatile("rdtsc" : "=d" (hi), "=a" (lo)); \ + ((u_int64_t)hi << 32) | (u_int64_t)lo; \ +}) + +#define rdpmc(pmc) \ +({ \ + u_int32_t hi, lo; \ + __asm __volatile("rdpmc" \ + : "=d" (hi), "=a" (lo) : "c" (pmc)); \ + hi &= 0xffffff; \ + (((u_int64_t)hi << 32) | (u_int64_t)lo); \ +}) + #ifdef _KERNEL +#define rdmsr(msr) \ +({ \ + u_int32_t hi, lo; \ + __asm __volatile("rdmsr" \ + : "=d" (hi), "=a" (lo) : "c" (msr)); \ + ((u_int64_t)hi << 32) | (u_int64_t) lo; \ +}) + +#define wrmsr(msr, v) \ +({ \ + __asm __volatile("wrmsr" : \ + : "a" ((u_int64_t)v & 0xffffffff), \ + "d" ((u_int64_t)v >> 32), "c" (msr)); \ +}) + void pctrattach(int); int pctropen(dev_t, int, int, struct proc *); int pctrclose(dev_t, int, int, struct proc *); -int pctrioctl(dev_t, u_int64_t, caddr_t, int, struct proc *); -int pctrsel(int fflag, u_int32_t, u_int32_t); +int pctrioctl(dev_t, u_long, caddr_t, int, struct proc *); #endif /* _KERNEL */ #endif /* ! _AMD64_PCTR_H_ */ diff --git a/sys/arch/i386/i386/pctr.c b/sys/arch/i386/i386/pctr.c index bc04c0cc5c8..3eb1f869026 100644 --- a/sys/arch/i386/i386/pctr.c +++ b/sys/arch/i386/i386/pctr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pctr.c,v 1.22 2006/11/29 20:03:20 dim Exp $ */ +/* $OpenBSD: pctr.c,v 1.23 2007/10/17 02:30:25 deraadt Exp $ */ /* * Pentium performance counter driver for OpenBSD. @@ -22,87 +22,119 @@ #include <machine/cpu.h> #include <machine/specialreg.h> -pctrval pctr_idlcnt; /* Gets incremented in locore.s */ - -int pctr_isintel; +#define PCTR_AMD_NUM PCTR_NUM +#define PCTR_INTEL_NUM 2 /* Intel supports only 2 counters */ #define usetsc (cpu_feature & CPUID_TSC) #define usep5ctr (pctr_isintel && (((cpu_id >> 8) & 15) == 5) && \ (((cpu_id >> 4) & 15) > 0)) -#define usep6ctr (pctr_isintel && ((cpu_id >> 8) & 15) == 6) +#define usepctr ((pctr_isamd || pctr_isintel) && \ + ((cpu_id >> 8) & 15) >= 6) + +u_int64_t pctr_idlcnt; /* Gets incremented in locore.S */ + +int pctr_isamd; +int pctr_isintel; + +static int p5ctrsel(int fflag, u_int cmd, u_int fn); +static int pctrsel(int fflag, u_int cmd, u_int fn); +static void pctrrd(struct pctrst *); +static void pctrrd(struct pctrst *); + +static void +p5ctrrd(struct pctrst *st) +{ + u_int msr11; + + msr11 = rdmsr(P5MSR_CTRSEL); + st->pctr_fn[0] = msr11 & 0xffff; + st->pctr_fn[1] = msr11 >> 16; + __asm __volatile("cli"); + st->pctr_tsc = rdtsc(); + st->pctr_hwc[0] = rdmsr(P5MSR_CTR0); + st->pctr_hwc[1] = rdmsr(P5MSR_CTR1); + __asm __volatile("sti"); +} -void pctrattach(int); -int pctropen(dev_t, int, int, struct proc *); -int pctrclose(dev_t, int, int, struct proc *); -int pctrioctl(dev_t, u_long, caddr_t, int, struct proc *); -int p5ctrsel(int fflag, u_int cmd, u_int fn); -static __inline void p5ctrrd(struct pctrst *st); -int p6ctrsel(int fflag, u_int cmd, u_int fn); -static __inline void p6ctrrd(struct pctrst *st); +static void +pctrrd(struct pctrst *st) +{ + int i, num, reg; + + num = pctr_isamd ? PCTR_AMD_NUM : PCTR_INTEL_NUM; + reg = pctr_isamd ? MSR_K7_EVNTSEL0 : P6MSR_CTRSEL0; + for (i = 0; i < num; i++) + st->pctr_fn[i] = rdmsr(reg + i); + __asm __volatile("cli"); + st->pctr_tsc = rdtsc(); + for (i = 0; i < num; i++) + st->pctr_hwc[i] = rdpmc(i); + __asm __volatile("sti"); +} void pctrattach(int num) { + if (num > 1) return; - pctr_isintel = (strcmp(cpu_vendor, "GenuineIntel") == 0); + pctr_isamd = (strcmp(cpu_vendor, "AuthenticAMD") == 0); + if (!pctr_isamd) + pctr_isintel = (strcmp(cpu_vendor, "GenuineIntel") == 0); - if (usep6ctr) + if (usepctr) { /* Enable RDTSC and RDPMC instructions from user-level. */ __asm __volatile ("movl %%cr4,%%eax\n" "\tandl %0,%%eax\n" "\torl %1,%%eax\n" "\tmovl %%eax,%%cr4" :: "i" (~CR4_TSD), "i" (CR4_PCE) : "eax"); - else if (usetsc) + printf("pctr: user-level performance counters enabled\n"); + } else if (usetsc) { /* Enable RDTSC instruction from user-level. */ __asm __volatile ("movl %%cr4,%%eax\n" "\tandl %0,%%eax\n" "\tmovl %%eax,%%cr4" :: "i" (~CR4_TSD) : "eax"); - - if (usep6ctr) - printf("pctr: 686-class user-level performance counters enabled\n"); - else if (usep5ctr) - printf("pctr: 586-class performance counters and user-level cycle counter enabled\n"); - else if (usetsc) printf("pctr: user-level cycle counter enabled\n"); - else - printf("pctr: no performance counters in CPU\n"); + } else if (usep5ctr) + printf("pctr: 586-class performance counters and user-level " + " cycle counter enabled\n"); } int pctropen(dev_t dev, int oflags, int devtype, struct proc *p) { + if (minor(dev)) - return ENXIO; - return 0; + return (ENXIO); + return (0); } int pctrclose(dev_t dev, int oflags, int devtype, struct proc *p) { - return 0; + + return (0); } int p5ctrsel(int fflag, u_int cmd, u_int fn) { pctrval msr11; - int msr; - int shift; + int msr, shift; cmd -= PCIOCS0; if (cmd > 1) - return EINVAL; + return (EINVAL); msr = P5MSR_CTR0 + cmd; shift = cmd ? 0x10 : 0; if (!(fflag & FWRITE)) - return EPERM; + return (EPERM); if (fn >= 0x200) - return EINVAL; + return (EINVAL); msr11 = rdmsr(P5MSR_CTRSEL); msr11 &= ~(0x1ffLL << shift); @@ -110,70 +142,49 @@ p5ctrsel(int fflag, u_int cmd, u_int fn) wrmsr(P5MSR_CTRSEL, msr11); wrmsr(msr, 0); - return 0; -} - -static __inline void -p5ctrrd(struct pctrst *st) -{ - u_int msr11; - - msr11 = rdmsr(P5MSR_CTRSEL); - st->pctr_fn[0] = msr11 & 0xffff; - st->pctr_fn[1] = msr11 >> 16; - __asm __volatile("cli"); - st->pctr_tsc = rdtsc(); - st->pctr_hwc[0] = rdmsr(P5MSR_CTR0); - st->pctr_hwc[1] = rdmsr(P5MSR_CTR1); - __asm __volatile("sti"); + return (0); } int -p6ctrsel(int fflag, u_int cmd, u_int fn) +pctrsel(int fflag, u_int cmd, u_int fn) { int msrsel, msrval; cmd -= PCIOCS0; - if (cmd > 1) - return EINVAL; - msrsel = P6MSR_CTRSEL0 + cmd; - msrval = P6MSR_CTR0 + cmd; + if (pctr_isamd) { + if (cmd > PCTR_AMD_NUM-1) + return (EINVAL); + msrsel = MSR_K7_EVNTSEL0 + cmd; + msrval = MSR_K7_PERFCTR0 + cmd; + } else { + if (cmd > PCTR_INTEL_NUM-1) + return (EINVAL); + msrsel = P6MSR_CTRSEL0 + cmd; + msrval = P6MSR_CTR0 + cmd; + } if (!(fflag & FWRITE)) - return EPERM; + return (EPERM); if (fn & 0x380000) - return EINVAL; + return (EINVAL); wrmsr(msrval, 0); wrmsr(msrsel, fn); wrmsr(msrval, 0); - return 0; -} - -static __inline void -p6ctrrd(struct pctrst *st) -{ - st->pctr_fn[0] = rdmsr(P6MSR_CTRSEL0); - st->pctr_fn[1] = rdmsr(P6MSR_CTRSEL1); - __asm __volatile("cli"); - st->pctr_tsc = rdtsc(); - st->pctr_hwc[0] = rdpmc(0); - st->pctr_hwc[1] = rdpmc(1); - __asm __volatile("sti"); + return (0); } - int pctrioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { switch (cmd) { case PCIOCRD: { - struct pctrst *st = (void *)data; + struct pctrst *st = (struct pctrst *)data; - if (usep6ctr) - p6ctrrd(st); + if (usepctr) + pctrrd(st); else if (usep5ctr) p5ctrrd(st); else { @@ -182,16 +193,16 @@ pctrioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) st->pctr_tsc = rdtsc(); } st->pctr_idl = pctr_idlcnt; - return 0; + return (0); } case PCIOCS0: case PCIOCS1: - if (usep6ctr) - return p6ctrsel(fflag, cmd, *(u_int *) data); + if (usepctr) + return (pctrsel(fflag, cmd, *(u_int *)data)); if (usep5ctr) - return p5ctrsel(fflag, cmd, *(u_int *) data); - return ENODEV; + return (p5ctrsel(fflag, cmd, *(u_int *)data)); + return (ENODEV); default: - return EINVAL; + return (EINVAL); } } diff --git a/sys/arch/i386/include/pctr.h b/sys/arch/i386/include/pctr.h index 3deb3e47582..d4f5b80d316 100644 --- a/sys/arch/i386/include/pctr.h +++ b/sys/arch/i386/include/pctr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pctr.h,v 1.12 2003/05/27 23:52:01 fgsch Exp $ */ +/* $OpenBSD: pctr.h,v 1.13 2007/10/17 02:30:25 deraadt Exp $ */ /* * Pentium performance counter driver for OpenBSD. @@ -14,73 +14,81 @@ #include <sys/ioccom.h> -typedef u_quad_t pctrval; +typedef u_int64_t pctrval; -#define PCTR_NUM 2 +#define PCTR_NUM 4 struct pctrst { - u_int pctr_fn[PCTR_NUM]; /* Current settings of hardware counters */ + u_int pctr_fn[PCTR_NUM]; /* Current settings of counters */ pctrval pctr_tsc; /* Free-running 64-bit cycle counter */ - pctrval pctr_hwc[PCTR_NUM]; /* Values of the hardware counters */ + pctrval pctr_hwc[PCTR_NUM]; /* Values of the hardware counters */ pctrval pctr_idl; /* Iterations of the idle loop */ }; /* Bit values in fn fields and PIOCS ioctl's */ -#define P5CTR_K 0x40 /* Monitor kernel-level events */ -#define P5CTR_U 0x80 /* Monitor user-level events */ -#define P5CTR_C 0x100 /* count cycles rather than events */ +#define P5CTR_K 0x40 /* Monitor kernel-level events */ +#define P5CTR_U 0x80 /* Monitor user-level events */ +#define P5CTR_C 0x100 /* count cycles rather than events */ -#define P6CTR_U 0x010000 /* Monitor user-level events */ -#define P6CTR_K 0x020000 /* Monitor kernel-level events */ -#define P6CTR_E 0x040000 /* Edge detect */ -#define P6CTR_EN 0x400000 /* Enable counters (counter 0 only) */ -#define P6CTR_I 0x800000 /* Invert counter mask */ +#define P6CTR_U 0x010000 /* Monitor user-level events */ +#define P6CTR_K 0x020000 /* Monitor kernel-level events */ +#define P6CTR_E 0x040000 /* Edge detect */ +#define P6CTR_EN 0x400000 /* Enable counters (counter 0 only) */ +#define P6CTR_I 0x800000 /* Invert counter mask */ /* Unit Mask bits */ -#define P6CTR_UM_M 0x0800 /* Modified cache lines */ -#define P6CTR_UM_E 0x0400 /* Exclusive cache lines */ -#define P6CTR_UM_S 0x0200 /* Shared cache lines */ -#define P6CTR_UM_I 0x0100 /* Invalid cache lines */ -#define P6CTR_UM_MESI (P6CTR_UM_M|P6CTR_UM_E|P6CTR_UM_S|P6CTR_UM_I) -#define P6CTR_UM_A 0x2000 /* Any initiator (as opposed to self) */ - -#define P6CTR_CM_SHIFT 24 /* Left shift for counter mask */ - -/* ioctl to set which counter a device tracks. */ -#define PCIOCRD _IOR('c', 1, struct pctrst) /* Read counter value */ -#define PCIOCS0 _IOW('c', 8, unsigned int) /* Set counter 0 function */ -#define PCIOCS1 _IOW('c', 9, unsigned int) /* Set counter 1 function */ +#define P6CTR_UM_M 0x0800 /* Modified cache lines */ +#define P6CTR_UM_E 0x0400 /* Exclusive cache lines */ +#define P6CTR_UM_S 0x0200 /* Shared cache lines */ +#define P6CTR_UM_I 0x0100 /* Invalid cache lines */ +#define P6CTR_UM_MESI (P6CTR_UM_M|P6CTR_UM_E|P6CTR_UM_S|P6CTR_UM_I) +#define P6CTR_UM_A 0x2000 /* Any initiator */ + +#define P6CTR_UM_SHIFT 8 /* Left shift for unit mask */ +#define P6CTR_CM_SHIFT 24 /* Left shift for counter mask */ + +/* ioctl to set which counter a device tracks */ +#define PCIOCRD _IOR('c', 1, struct pctrst) /* Read counter value */ +#define PCIOCS0 _IOW('c', 8, unsigned int) /* Set counter 0 function */ +#define PCIOCS1 _IOW('c', 9, unsigned int) /* Set counter 1 function */ +#define PCIOCS2 _IOW('c', 10, unsigned int) /* Set counter 0 function */ +#define PCIOCS3 _IOW('c', 11, unsigned int) /* Set counter 1 function */ #define _PATH_PCTR "/dev/pctr" -#define rdtsc() \ -({ \ - pctrval v; \ - __asm __volatile ("rdtsc" : "=A" (v)); \ - v; \ +#define rdtsc() \ +({ \ + pctrval v; \ + __asm __volatile ("rdtsc" : "=A" (v)); \ + v; \ }) /* Read the performance counters (Pentium Pro only) */ -#define rdpmc(ctr) \ -({ \ - pctrval v; \ - __asm __volatile ("rdpmc\n" \ - "\tandl $0xff, %%edx" \ - : "=A" (v) : "c" (ctr)); \ - v; \ +#define rdpmc(ctr) \ +({ \ + pctrval v; \ + __asm __volatile ("rdpmc\n" \ + "\tandl $0xff, %%edx" \ + : "=A" (v) : "c" (ctr)); \ + v; \ }) #ifdef _KERNEL #define rdmsr(msr) \ ({ \ - pctrval v; \ - __asm __volatile ("rdmsr" : "=A" (v) : "c" (msr)); \ - v; \ + pctrval v; \ + __asm __volatile ("rdmsr" : "=A" (v) : "c" (msr)); \ + v; \ }) #define wrmsr(msr, v) \ - __asm __volatile ("wrmsr" :: "A" ((u_quad_t) (v)), "c" (msr)); + __asm __volatile ("wrmsr" :: "A" ((u_quad_t) (v)), "c" (msr)); + +void pctrattach(int); +int pctropen(dev_t, int, int, struct proc *); +int pctrclose(dev_t, int, int, struct proc *); +int pctrioctl(dev_t, u_long, caddr_t, int, struct proc *); #endif /* _KERNEL */ #endif /* ! _I386_PCTR_H_ */ diff --git a/sys/arch/i386/include/specialreg.h b/sys/arch/i386/include/specialreg.h index bc186de981f..7dc9f548496 100644 --- a/sys/arch/i386/include/specialreg.h +++ b/sys/arch/i386/include/specialreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: specialreg.h,v 1.31 2007/05/29 21:01:56 tedu Exp $ */ +/* $OpenBSD: specialreg.h,v 1.32 2007/10/17 02:30:25 deraadt Exp $ */ /* $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $ */ /*- @@ -245,6 +245,14 @@ /* AMD MSRs */ #define MSR_K6_EPMR 0xc0000086 +#define MSR_K7_EVNTSEL0 0xc0010000 +#define MSR_K7_EVNTSEL1 0xc0010001 +#define MSR_K7_EVNTSEL2 0xc0010002 +#define MSR_K7_EVNTSEL3 0xc0010003 +#define MSR_K7_PERFCTR0 0xc0010004 +#define MSR_K7_PERFCTR1 0xc0010005 +#define MSR_K7_PERFCTR2 0xc0010006 +#define MSR_K7_PERFCTR3 0xc0010007 /* * AMD K8 (Opteron) MSRs. |