summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/conf/files.i3863
-rw-r--r--sys/i386/conf/options.i3862
-rw-r--r--sys/i386/i386/machdep.c9
-rw-r--r--sys/i386/i386/mem.c38
-rw-r--r--sys/i386/i386/perfmon.c295
-rw-r--r--sys/i386/include/cpufunc.h36
-rw-r--r--sys/i386/include/perfmon.h261
7 files changed, 638 insertions, 6 deletions
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 5c40866..65f44f9 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.130 1996/03/02 19:37:34 peter Exp $
+# $Id: files.i386,v 1.131 1996/03/15 07:49:02 peter Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -50,6 +50,7 @@ i386/i386/math_emulate.c optional math_emulate
i386/i386/mem.c standard
i386/i386/microtime.s standard
i386/i386/ns_cksum.c optional ns
+i386/i386/perfmon.c optional perfmon
i386/i386/pmap.c standard
i386/i386/procfs_machdep.c standard
i386/i386/support.s standard
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index eb474eb..42ab489 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,3 +1,4 @@
+# $Id$
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -9,3 +10,4 @@ PANIC_REBOOT_WAIT_TIME opt_machdep.h
LARGEMEM opt_machdep.h
MAXMEM opt_machdep.h
LINUX opt_linux.h
+PERFMON opt_perfmon.h
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 014d3fb..e2f7699 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.177 1996/03/03 01:57:43 jkh Exp $
+ * $Id: machdep.c,v 1.178 1996/03/11 02:21:42 hsu Exp $
*/
#include "npx.h"
@@ -44,6 +44,7 @@
#include "opt_ddb.h"
#include "opt_bounce.h"
#include "opt_machdep.h"
+#include "opt_perfmon.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -109,6 +110,9 @@
#include <machine/devconf.h>
#include <machine/bootinfo.h>
#include <machine/md_var.h>
+#ifdef PERFMON
+#include <machine/perfmon.h>
+#endif
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
@@ -649,6 +653,9 @@ identifycpu()
default:
break;
}
+#ifdef PERFMON
+ perfmon_init();
+#endif
dev_attach(&kdc_cpu0);
}
diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c
index 1439398..e60c99e 100644
--- a/sys/i386/i386/mem.c
+++ b/sys/i386/i386/mem.c
@@ -38,13 +38,15 @@
*
* from: Utah $Hdr: mem.c 1.13 89/10/08$
* from: @(#)mem.c 7.2 (Berkeley) 5/9/91
- * $Id: mem.c,v 1.28 1995/12/27 11:18:29 markm Exp $
+ * $Id: mem.c,v 1.29 1995/12/31 09:32:16 joerg Exp $
*/
/*
* Memory special file
*/
+#include "opt_perfmon.h"
+
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/buf.h>
@@ -60,6 +62,9 @@
#include <machine/cpu.h>
#include <machine/random.h>
#include <machine/psl.h>
+#ifdef PERFMON
+#include <machine/perfmon.h>
+#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -90,6 +95,9 @@ static void *random_devfs_token;
static void *urandom_devfs_token;
static void *zero_devfs_token;
static void *io_devfs_token;
+#ifdef PERFMON
+static void *perfmon_devfs_token;
+#endif
static void memdevfs_init __P((void));
@@ -111,6 +119,10 @@ memdevfs_init()
"/", "zero", &mem_cdevsw, 12, DV_CHR, 0, 0, 0666);
io_devfs_token = devfs_add_devsw(
"/", "io", &mem_cdevsw, 14, DV_CHR, 0, 0, 0600);
+#ifdef PERFMON
+ perfmon_devfs_token = devfs_add_devsw(
+ "/", "perfmon", &mem_cdevsw, 32, DV_CHR, 0, 0, 0666);
+#endif /* PERFMON */
}
#endif /* DEVFS */
@@ -126,6 +138,10 @@ mmclose(dev, flags, fmt, p)
struct trapframe *fp;
switch (minor(dev)) {
+#ifdef PERFMON
+ case 32:
+ return perfmon_close(dev, flags, fmt, p);
+#endif
case 14:
fp = (struct trapframe *)curproc->p_md.md_regs;
fp->tf_eflags &= ~PSL_IOPL;
@@ -146,6 +162,12 @@ mmopen(dev, flags, fmt, p)
struct trapframe *fp;
switch (minor(dev)) {
+ case 32:
+#ifdef PERFMON
+ return perfmon_open(dev, flags, fmt, p);
+#else
+ return ENODEV;
+#endif
case 14:
fp = (struct trapframe *)curproc->p_md.md_regs;
fp->tf_eflags |= PSL_IOPL;
@@ -378,8 +400,18 @@ mmioctl(dev, cmd, cmdarg, flags, p)
u_int16_t interrupt_mask;
int error;
- if (minor(dev) != 3 && minor(dev) != 4)
- return (ENODEV);
+ switch(minor(dev)) {
+ case 3:
+ case 4:
+ break;
+
+#ifdef PERFMON
+ case 32:
+ return perfmon_ioctl(dev, cmd, cmdarg, flags, p);
+#endif
+ default:
+ return ENODEV;
+ }
if (*(u_int16_t *)cmdarg >= 16)
return (EINVAL);
diff --git a/sys/i386/i386/perfmon.c b/sys/i386/i386/perfmon.c
new file mode 100644
index 0000000..290d339
--- /dev/null
+++ b/sys/i386/i386/perfmon.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/ioccom.h>
+
+#include <machine/cpu.h>
+#include <machine/cputypes.h>
+#include <machine/clock.h>
+#include <machine/perfmon.h>
+
+static int perfmon_inuse;
+static int perfmon_cpuok;
+static int msr_ctl[NPMC];
+static int msr_pmc[NPMC];
+
+/*
+ * Must be called after cpu_class is set up.
+ */
+void
+perfmon_init(void)
+{
+ switch(cpu_class) {
+ case CPUCLASS_586: /* assume it's the same for now */
+ case CPUCLASS_686:
+ perfmon_cpuok = 1;
+ msr_ctl[0] = 0x186;
+ msr_ctl[1] = 0x187;
+ msr_pmc[0] = 0xc1;
+ msr_pmc[1] = 0xc2;
+ break;
+
+ default:
+ perfmon_cpuok = 0;
+ break;
+ }
+}
+
+int
+perfmon_avail(void)
+{
+ return perfmon_cpuok;
+}
+
+int
+perfmon_setup(int pmc, unsigned int control)
+{
+ if (pmc < 0 || pmc >= NPMC)
+ return EINVAL;
+
+ perfmon_inuse |= (1 << pmc);
+ control &= ~(PMCF_SYS_FLAGS << 16);
+ wrmsr(msr_ctl[pmc], control);
+ wrmsr(msr_pmc[pmc], 0);
+ return 0;
+}
+
+int
+perfmon_get(int pmc, unsigned int *control)
+{
+ if (pmc < 0 || pmc >= NPMC)
+ return EINVAL;
+
+ if (perfmon_inuse & (1 << pmc)) {
+ *control = rdmsr(msr_ctl[pmc]);
+ return 0;
+ }
+ return EBUSY; /* XXX reversed sense */
+}
+
+int
+perfmon_fini(int pmc)
+{
+ if (pmc < 0 || pmc >= NPMC)
+ return EINVAL;
+
+ if (perfmon_inuse & (1 << pmc)) {
+ perfmon_stop(pmc);
+ perfmon_inuse &= ~(1 << pmc);
+ return 0;
+ }
+ return EBUSY; /* XXX reversed sense */
+}
+
+int
+perfmon_start(int pmc)
+{
+ /*
+ * XXX - Current Intel design does not allow counters to be enabled
+ * independently.
+ */
+ if (pmc != PMC_ALL)
+ return EINVAL;
+
+#if 0
+ if (perfmon_inuse & (1 << pmc)) {
+ wrmsr(msr_ctl[pmc], rdmsr(msr_ctl[pmc]) | (PMCF_EN << 16));
+ return 0;
+ }
+#else
+ if (perfmon_inuse) {
+ wrmsr(msr_ctl[0], rdmsr(msr_ctl[0]) | (PMCF_EN << 16));
+ return 0;
+ }
+#endif
+ return EBUSY;
+}
+
+int
+perfmon_stop(int pmc)
+{
+ /*
+ * XXX - Current Intel design does not allow counters to be enabled
+ * independently.
+ */
+ if (pmc != PMC_ALL)
+ return EINVAL;
+
+#if 0
+ if (perfmon_inuse & (1 << pmc)) {
+ wrmsr(msr_ctl[pmc], rdmsr(msr_ctl[pmc]) & ~(PMCF_EN << 16));
+ return 0;
+ }
+#else
+ if (perfmon_inuse) {
+ wrmsr(msr_ctl[0], rdmsr(msr_ctl[0]) & ~(PMCF_EN << 16));
+ return 0;
+ }
+#endif
+ return EBUSY;
+}
+
+int
+perfmon_read(int pmc, quad_t *val)
+{
+ if (pmc < 0 || pmc >= NPMC)
+ return EINVAL;
+
+ if (perfmon_inuse & (1 << pmc)) {
+ *val = rdmsr(msr_pmc[pmc]);
+ return 0;
+ }
+
+ return EBUSY;
+}
+
+int
+perfmon_reset(int pmc)
+{
+ if (pmc < 0 || pmc >= NPMC)
+ return EINVAL;
+
+ if (perfmon_inuse & (1 << pmc)) {
+ wrmsr(msr_pmc[pmc], 0);
+ return 0;
+ }
+ return EBUSY;
+}
+
+/*
+ * Now the user-mode interface, called from a subdevice of mem.c.
+ */
+static int writer;
+static int writerpmc;
+
+int
+perfmon_open(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ if (!perfmon_cpuok)
+ return ENXIO;
+
+ if (flags & FWRITE) {
+ if (writer) {
+ return EBUSY;
+ } else {
+ writer = 1;
+ writerpmc = 0;
+ }
+ }
+ return 0;
+}
+
+int
+perfmon_close(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ if (flags & FWRITE) {
+ int i;
+
+ for (i = 0; i < NPMC; i++) {
+ if (writerpmc & (1 << i))
+ perfmon_fini(i);
+ }
+ writer = 0;
+ }
+ return 0;
+}
+
+int
+perfmon_ioctl(dev_t dev, int cmd, caddr_t param, int flags, struct proc *p)
+{
+ struct pmc *pmc;
+ struct pmc_data *pmcd;
+ struct pmc_tstamp *pmct;
+ int *ip;
+ int rv;
+
+ switch(cmd) {
+ case PMIOSETUP:
+ if (!(flags & FWRITE))
+ return EPERM;
+ pmc = (struct pmc *)param;
+
+ rv = perfmon_setup(pmc->pmc_num, pmc->pmc_val);
+ if (!rv) {
+ writerpmc |= (1 << pmc->pmc_num);
+ }
+ break;
+
+ case PMIOGET:
+ pmc = (struct pmc *)param;
+ rv = perfmon_get(pmc->pmc_num, &pmc->pmc_val);
+ break;
+
+ case PMIOSTART:
+ if (!(flags & FWRITE))
+ return EPERM;
+
+ ip = (int *)param;
+ rv = perfmon_start(*ip);
+ break;
+
+ case PMIOSTOP:
+ if (!(flags & FWRITE))
+ return EPERM;
+
+ ip = (int *)param;
+ rv = perfmon_stop(*ip);
+ break;
+
+ case PMIORESET:
+ if (!(flags & FWRITE))
+ return EPERM;
+
+ ip = (int *)param;
+ rv = perfmon_reset(*ip);
+ break;
+
+ case PMIOREAD:
+ pmcd = (struct pmc_data *)param;
+ rv = perfmon_read(pmcd->pmcd_num, &pmcd->pmcd_value);
+ break;
+
+ case PMIOTSTAMP:
+ pmct = (struct pmc_tstamp *)param;
+ pmct->pmct_rate = i586_ctr_rate >> I586_CTR_RATE_SHIFT;
+ pmct->pmct_value = rdtsc();
+ rv = 0;
+ break;
+
+ default:
+ rv = ENOTTY;
+ }
+
+ return rv;
+}
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index ecb7e00..6a1235a 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cpufunc.h,v 1.44 1995/12/28 23:34:17 davidg Exp $
+ * $Id: cpufunc.h,v 1.45 1996/01/16 07:42:08 bde Exp $
*/
/*
@@ -296,6 +296,36 @@ write_eflags(u_long ef)
__asm __volatile("pushl %0; popfl" : : "r" (ef));
}
+static __inline long long
+rdmsr(unsigned msr)
+{
+ long long rv;
+ __asm __volatile(".byte 0x0f, 0x32" : "=A" (rv) : "c" (msr));
+ return rv;
+}
+
+static __inline long long
+rdtsc(void)
+{
+ long long rv;
+ __asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
+ return rv;
+}
+
+static __inline long long
+rdpmc(unsigned pmc)
+{
+ long long rv;
+ __asm __volatile(".byte 0x0f, 0x33" : "=A" (rv) : "c" (pmc));
+ return rv;
+}
+
+static __inline void
+wrmsr(unsigned msr, long long newval)
+{
+ __asm __volatile(".byte 0x0f, 0x33" : : "A" (newval), "c" (msr));
+}
+
#else /* !__GNUC__ */
int bdb __P((void));
@@ -318,6 +348,10 @@ void pmap_update __P((void));
u_long read_eflags __P((void));
u_long rcr2 __P((void));
void write_eflags __P((u_long ef));
+quad_t rdmsr __P((unsigned msr));
+quad_t rdtsc __P((void));
+quad_t rdpmc __P((unsigned pmc));
+void wrmsr __P((unsigned msr, quad_t newval));
#endif /* __GNUC__ */
diff --git a/sys/i386/include/perfmon.h b/sys/i386/include/perfmon.h
new file mode 100644
index 0000000..8aec6df
--- /dev/null
+++ b/sys/i386/include/perfmon.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright 1996 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Interface to performance-monitoring counters for Intel Pentium and
+ * Pentium Pro CPUs.
+ */
+
+#ifndef _MACHINE_PERFMON_H_
+#define _MACHINE_PERFMON_H_ 1
+
+#ifndef KERNEL
+#include <sys/ioccom.h>
+#endif
+
+#define NPMC 2
+
+#define PMIOSETUP _IOW('5', 1, struct pmc)
+#define PMIOGET _IOWR('5', 7, struct pmc)
+#define PMIOSTART _IOW('5', 2, int)
+#define PMIOSTOP _IOW('5', 3, int)
+#define PMIOREAD _IOWR('5', 4, struct pmc_data)
+#define PMIORESET _IOW('5', 5, int)
+#define PMIOTSTAMP _IOR('5', 6, struct pmc_tstamp)
+
+struct pmc {
+ int pmc_num;
+ union {
+ struct {
+ unsigned char pmcus_event;
+ unsigned char pmcus_unit;
+ unsigned char pmcus_flags;
+ unsigned char pmcus_mask;
+ } pmcu_s;
+ unsigned int pmcu_val;
+ } pmc_pmcu;
+};
+
+#define PMC_ALL (-1)
+
+#define pmc_event pmc_pmcu.pmcu_s.pmcus_event
+#define pmc_unit pmc_pmcu.pmcu_s.pmcus_unit
+#define pmc_flags pmc_pmcu.pmcu_s.pmcus_flags
+#define pmc_mask pmc_pmcu.pmcu_s.pmcus_mask
+#define pmc_val pmc_pmcu.pmcu_val
+
+#define PMCF_USR 0x01 /* count events in user mode */
+#define PMCF_OS 0x02 /* count events in kernel mode */
+#define PMCF_E 0x04 /* use edge-detection mode */
+#define PMCF_PC 0x08 /* PMx output pin control */
+#define PMCF_INT 0x10 /* APIC interrupt enable (do not use) */
+#define PMCF_EN 0x40 /* enable counters */
+#define PMCF_INV 0x80 /* invert counter mask comparison */
+
+#define PMCF_SYS_FLAGS (PMCF_INT | PMCF_EN) /* user cannot set */
+
+struct pmc_data {
+ int pmcd_num;
+ quad_t pmcd_value;
+};
+
+struct pmc_tstamp {
+ int pmct_rate;
+ quad_t pmct_value;
+};
+
+#ifndef KERNEL
+
+#define _PATH_PERFMON "/dev/perfmon"
+
+#else
+
+/*
+ * Intra-kernel interface to performance monitoring counters
+ */
+void perfmon_init __P((void));
+int perfmon_avail __P((void));
+int perfmon_setup __P((int, unsigned int));
+int perfmon_get __P((int, unsigned int *));
+int perfmon_fini __P((int));
+int perfmon_start __P((int));
+int perfmon_stop __P((int));
+int perfmon_read __P((int, quad_t *));
+int perfmon_reset __P((int));
+
+/*
+ * We pass the device down this interface because in the future
+ * the different counters might be accessed through separate devices.
+ */
+int perfmon_close __P((dev_t, int, int, struct proc *));
+int perfmon_open __P((dev_t, int, int, struct proc *));
+int perfmon_ioctl __P((dev_t, int, caddr_t, int, struct proc *));
+#endif /* KERNEL */
+
+/*
+ * Pentium Pro performance counters, from Appendix B.
+ */
+/* Data Cache Unit */
+#define PMC6_DATA_MEM_REFS 0x43
+#define PMC6_DCU_LINES_IN 0x45
+#define PMC6_DCU_M_LINES_IN 0x46
+#define PMC6_DCU_M_LINES_OUT 0x47
+#define PMC6_DCU_MISS_OUTSTANDING 0x48
+
+/* Instruction Fetch Unit */
+#define PMC6_IFU_IFETCH 0x80
+#define PMC6_IFU_IFETCH_MISS 0x81
+#define PMC6_ITLB_MISS 0x85
+#define PMC6_IFU_MEM_STALL 0x86
+#define PMC6_ILD_STALL 0x87
+
+/* L2 Cache */
+#define PMC6_L2_IFETCH 0x28 /* MESI */
+#define PMC6_L2_LD 0x29 /* MESI */
+#define PMC6_L2_ST 0x2a /* MESI */
+#define PMC6_L2_LINES_IN 0x24
+#define PMC6_L2_LINES_OUT 0x26
+#define PMC6_L2_M_LINES_INM 0x25
+#define PMC6_L2_M_LINES_OUTM 0x27
+#define PMC6_L2_RQSTS 0x2e /* MESI */
+#define PMC6_L2_ADS 0x21
+#define PMC6_L2_DBUS_BUSY 0x22
+#define PMC6_L2_DBUS_BUSY_RD 0x23
+
+/* External Bus Logic */
+#define PMC6_BUS_DRDY_CLOCKS 0x62
+#define PMC6_BUS_LOCK_CLOCKS 0x63
+#define PMC6_BUS_REQ_OUTSTANDING 0x60
+#define PMC6_BUS_TRAN_BRD 0x65
+#define PMC6_BUS_TRAN_RFO 0x66
+#define PMC6_BUS_TRAN_WB 0x67
+#define PMC6_BUS_TRAN_IFETCH 0x68
+#define PMC6_BUS_TRAN_INVAL 0x69
+#define PMC6_BUS_TRAN_PWR 0x6a
+#define PMC6_BUS_TRAN_P 0x6b
+#define PMC6_BUS_TRAN_IO 0x6c
+#define PMC6_BUS_TRAN_DEF 0x6d
+#define PMC6_BUS_TRAN_BURST 0x6e
+#define PMC6_BUS_TRAN_ANY 0x70
+#define PMC6_BUS_TRAN_MEM 0x6f
+#define PMC6_BUS_DATA_RCV 0x64
+#define PMC6_BUS_BNR_DRV 0x61
+#define PMC6_BUS_HIT_DRV 0x7a
+#define PMC6_BUS_HITM_DRV 0x7b
+#define PMC6_BUS_SNOOP_STALL 0x7e
+
+/* Floating Point Unit */
+#define PMC6_FLOPS 0xc1 /* counter 0 only */
+#define PMC6_FP_COMP_OPS_EXE 0x10 /* counter 0 only */
+#define PMC6_FP_ASSIST 0x11 /* counter 1 only */
+#define PMC6_MUL 0x12 /* counter 1 only */
+#define PMC6_DIV 0x13 /* counter 1 only */
+#define PMC6_CYCLES_DIV_BUSY 0x14 /* counter 0 only */
+
+/* Memory Ordering */
+#define PMC6_LD_BLOCKS 0x03
+#define PMC6_SB_DRAINS 0x04
+#define PMC6_MISALIGN_MEM_REF 0x05
+
+/* Instruction Decoding and Retirement */
+#define PMC6_INST_RETIRED 0xc0
+#define PMC6_UOPS_RETIRED 0xc2
+#define PMC6_INST_DECODER 0xd0 /* (sic) */
+
+/* Interrupts */
+#define PMC6_HW_INT_RX 0xc8
+#define PMC6_CYCLES_INT_MASKED 0xc6
+#define PMC6_CYCLES_INT_PENDING_AND_MASKED 0xc7
+
+/* Branches */
+#define PMC6_BR_INST_RETIRED 0xc4
+#define PMC6_BR_MISS_PRED_RETIRED 0xc5
+#define PMC6_BR_TAKEN_RETIRED 0xc9
+#define PMC6_BR_MISS_PRED_TAKEN_RET 0xca
+#define PMC6_BR_INST_DECODED 0xe0
+#define PMC6_BTB_MISSES 0xe2
+#define PMC6_BR_BOGUS 0xe4
+#define PMC6_BACLEARS 0xe6
+
+/* Stalls */
+#define PMC6_RESOURCE_STALLS 0xa2
+#define PMC6_PARTIAL_RAT_STALLS 0xd2
+
+/* Segment Register Loads */
+#define PMC6_SEGMENT_REG_LOADS 0x06
+
+/* Clocks */
+#define PMC6_CPU_CLK_UNHALTED 0x79
+
+/*
+ * Pentium Performance Counters
+ * This list comes from the Harvard people, not Intel.
+ */
+#define PMC5_DATA_READ 0
+#define PMC5_DATA_WRITE 1
+#define PMC5_DATA_TLB_MISS 2
+#define PMC5_DATA_READ_MISS 3
+#define PMC5_DATA_WRITE_MISS 4
+#define PMC5_WRITE_M_E 5
+#define PMC5_DATA_LINES_WBACK 6
+#define PMC5_DATA_CACHE_SNOOP 7
+#define PMC5_DATA_CACHE_SNOOP_HIT 8
+#define PMC5_MEM_ACCESS_BOTH 9
+#define PMC5_BANK_CONFLICTS 10
+#define PMC5_MISALIGNED_DATA 11
+#define PMC5_INST_READ 12
+#define PMC5_INST_TLB_MISS 13
+#define PMC5_INST_CACHE_MISS 14
+#define PMC5_SEGMENT_REG_LOAD 15
+#define PMC5_BRANCHES 18
+#define PMC5_BTB_HITS 19
+#define PMC5_BRANCH_TAKEN 20
+#define PMC5_PIPELINE_FLUSH 21
+#define PMC5_INST_EXECUTED 22
+#define PMC5_INST_EXECUTED_V 23
+#define PMC5_BUS_UTILIZATION 24
+#define PMC5_WRITE_BACKUP_STALL 25
+#define PMC5_DATA_READ_STALL 26
+#define PMC5_WRITE_E_M_STALL 27
+#define PMC5_LOCKED_BUS 28
+#define PMC5_IO_CYCLE 29
+#define PMC5_NONCACHE_MEMORY 30
+#define PMC5_ADDR_GEN_INTERLOCK 31
+#define PMC5_FLOPS 34
+#define PMC5_BP0_MATCH 35
+#define PMC5_BP1_MATCH 36
+#define PMC5_BP2_MATCH 37
+#define PMC5_BP3_MATCH 38
+#define PMC5_HW_INTR 39
+#define PMC5_DATA_RW 40
+#define PMC5_DATA_RW_MISS 41
+
+#endif /* _MACHINE_PERFMON_H_ */
OpenPOWER on IntegriCloud