i386: Remove perfmon performance monitoring facility
Remove the perfmon performance monitoring facility that was for Intel Pentium and Pentium Pro processors. Reviewed by: imp,mhorne,emaste Pull Request: https://github.com/freebsd/freebsd-src/pull/2155
This commit is contained in:
committed by
Warner Losh
parent
576c6e9620
commit
70ae0c4524
@@ -51,6 +51,14 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20260420: remove perfmon
|
||||
OLD_FILES+=boot/kernel/perfmon.ko
|
||||
OLD_FILES+=usr/share/man/man4/perfmon.4.gz
|
||||
OLD_FILES+=usr/share/examples/perfmon/Makefile
|
||||
OLD_FILES+=usr/share/examples/perfmon/README
|
||||
OLD_FILES+=usr/share/examples/perfmon/perfmon.c
|
||||
OLD_DIRS+=usr/share/examples/perfmon
|
||||
|
||||
# 20260402: posix_spawn_file_actions_addchdir lost _np suffix
|
||||
OLD_FILES+=usr/share/man/man3/posix_spawn_file_actions_addchdir_np.3.gz
|
||||
OLD_FILES+=usr/share/man/man3/posix_spawn_file_actions_addfchdir_np.3.gz
|
||||
|
||||
@@ -346,8 +346,6 @@
|
||||
..
|
||||
netgraph
|
||||
..
|
||||
perfmon
|
||||
..
|
||||
pf
|
||||
..
|
||||
ppi
|
||||
|
||||
@@ -22,7 +22,6 @@ LDIRS= BSD_daemon \
|
||||
mdoc \
|
||||
netgraph \
|
||||
oci \
|
||||
perfmon \
|
||||
ppi \
|
||||
ppp \
|
||||
ses \
|
||||
@@ -202,12 +201,6 @@ SE_OCI= \
|
||||
README \
|
||||
Containerfile.pkg
|
||||
|
||||
SE_DIRS+= perfmon
|
||||
SE_PERFMON= \
|
||||
Makefile \
|
||||
README \
|
||||
perfmon.c \
|
||||
|
||||
.if ${MK_PF} != "no"
|
||||
SE_DIRS+= pf
|
||||
.if ${MK_STAGING} == "no"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
PACKAGE=examples
|
||||
FILESDIR=${SHAREDIR}/examples/${PROG}
|
||||
PROG= perfmon
|
||||
MAN=
|
||||
|
||||
install:
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,23 +0,0 @@
|
||||
`perfmon' is a sample program to access the performance-monitoring
|
||||
counters on Pentium and Pentium Pro CPUs. See perfmon(4) for a
|
||||
description of this facility.
|
||||
|
||||
The program takes the following options:
|
||||
|
||||
-u count events in user mode
|
||||
-o count events in kernel mode
|
||||
(these two can be combined)
|
||||
|
||||
-e count events, not duration
|
||||
-l n run `n' loops (default 50)
|
||||
-s n sleep `n' seconds between loop iterations (default 0)
|
||||
|
||||
The following options are not implemented on Pentium CPUs:
|
||||
|
||||
-m n use count mask `n'
|
||||
-i invert sense of count mask comparison
|
||||
-U n use unit mask `n'
|
||||
|
||||
There is one mandatory argument, which is the event number to be
|
||||
monitored, defined in <machine/perfmon.h>. All numbers can be
|
||||
specified in any format acceptable to strtol(3).
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/perfmon.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int getnum(const char *, int, int);
|
||||
static void usage(const char *) __dead2;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int c, fd, num;
|
||||
int loops, i, sleeptime;
|
||||
char *cmd;
|
||||
struct pmc pmc;
|
||||
struct pmc_tstamp then, now;
|
||||
struct pmc_data value;
|
||||
quad_t *buf;
|
||||
double total;
|
||||
|
||||
pmc.pmc_num = 0;
|
||||
pmc.pmc_event = 0;
|
||||
pmc.pmc_unit = 0;
|
||||
pmc.pmc_flags = 0;
|
||||
pmc.pmc_mask = 0;
|
||||
cmd = NULL;
|
||||
loops = 50;
|
||||
sleeptime = 0;
|
||||
|
||||
while ((c = getopt(argc, argv, "s:l:uoeiU:m:c:")) != -1) {
|
||||
switch(c) {
|
||||
case 'u':
|
||||
pmc.pmc_flags |= PMCF_USR;
|
||||
break;
|
||||
case 'o':
|
||||
pmc.pmc_flags |= PMCF_OS;
|
||||
break;
|
||||
case 'e':
|
||||
pmc.pmc_flags |= PMCF_E;
|
||||
break;
|
||||
case 'i':
|
||||
pmc.pmc_flags |= PMCF_INV;
|
||||
break;
|
||||
case 'U':
|
||||
pmc.pmc_unit = getnum(optarg, 0, 256);
|
||||
break;
|
||||
case 'm':
|
||||
pmc.pmc_mask = getnum(optarg, 0, 256);
|
||||
break;
|
||||
case 'l':
|
||||
loops = getnum(optarg, 1, INT_MAX - 1);
|
||||
break;
|
||||
case 's':
|
||||
sleeptime = getnum(optarg, 0, INT_MAX - 1);
|
||||
break;
|
||||
case 'c':
|
||||
cmd = optarg;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind != 1)
|
||||
usage(argv[0]);
|
||||
|
||||
pmc.pmc_event = getnum(argv[optind], 0, 255);
|
||||
|
||||
buf = malloc((loops + 1) * sizeof *buf);
|
||||
if (!buf)
|
||||
err(1, "malloc(%lu)", (unsigned long)(loops +1) * sizeof *buf);
|
||||
|
||||
fd = open(_PATH_PERFMON, O_RDWR, 0);
|
||||
if (fd < 0)
|
||||
err(1, "open: " _PATH_PERFMON);
|
||||
|
||||
if (ioctl(fd, PMIOSETUP, &pmc) < 0)
|
||||
err(1, "ioctl(PMIOSETUP)");
|
||||
|
||||
if (ioctl(fd, PMIOTSTAMP, &then) < 0)
|
||||
err(1, "ioctl(PMIOTSTAMP)");
|
||||
|
||||
num = 0;
|
||||
if (ioctl(fd, PMIOSTART, &num) < 0)
|
||||
err(1, "ioctl(PMIOSTART)");
|
||||
|
||||
value.pmcd_num = 0;
|
||||
for (i = 0; i < loops; i++) {
|
||||
if (ioctl(fd, PMIOSTOP, &num) < 0)
|
||||
err(1, "ioctl(PMIOSTOP)");
|
||||
if (ioctl(fd, PMIOREAD, &value) < 0)
|
||||
err(1, "ioctl(PMIOREAD)");
|
||||
buf[i] = value.pmcd_value;
|
||||
if (ioctl(fd, PMIORESET, &value.pmcd_num) < 0)
|
||||
err(1, "ioctl(PMIORESET)");
|
||||
if (ioctl(fd, PMIOSTART, &num) < 0)
|
||||
err(1, "ioctl(PMIOSTART)");
|
||||
if (sleeptime)
|
||||
sleep(sleeptime);
|
||||
if (cmd)
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
if (ioctl(fd, PMIOSTOP, &num) < 0)
|
||||
err(1, "ioctl(PMIOSTOP)");
|
||||
if (ioctl(fd, PMIOREAD, &value) < 0)
|
||||
err(1, "ioctl(PMIOREAD)");
|
||||
buf[i] = value.pmcd_value;
|
||||
if (ioctl(fd, PMIOTSTAMP, &now) < 0)
|
||||
err(1, "ioctl(PMIOTSTAMP)");
|
||||
|
||||
total = 0;
|
||||
for (i = 1; i <= loops; i++) {
|
||||
printf("%d: %qd\n", i, buf[i]);
|
||||
total += buf[i];
|
||||
}
|
||||
printf("total: %f\nmean: %f\n", total, total / loops);
|
||||
|
||||
printf("clocks (at %d-MHz): %qd\n", now.pmct_rate,
|
||||
now.pmct_value - then.pmct_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getnum(const char *buf, int min, int max)
|
||||
{
|
||||
char *ep;
|
||||
long l;
|
||||
|
||||
errno = 0;
|
||||
l = strtol(buf, &ep, 0);
|
||||
if (*buf && !*ep && !errno) {
|
||||
if (l < min || l > max) {
|
||||
errx(1, "%s: must be between %d and %d",
|
||||
buf, min, max);
|
||||
}
|
||||
return (int)l;
|
||||
}
|
||||
|
||||
errx(1, "%s: parameter must be an integer", buf);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(const char *pname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-eiou] [-c command] [-l nloops] [-m mask] [-s sleeptime]\n"
|
||||
" [-U unit] counter\n",
|
||||
pname);
|
||||
exit(1);
|
||||
}
|
||||
@@ -6,7 +6,6 @@ MAN= apm.4 \
|
||||
npx.4 \
|
||||
pae.4 \
|
||||
pbio.4 \
|
||||
perfmon.4 \
|
||||
pnp.4 \
|
||||
pnpbios.4 \
|
||||
sbni.4 \
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
.\"
|
||||
.\" 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.
|
||||
.Dd March 26, 1996
|
||||
.Dt PERFMON 4 i386
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm perfmon
|
||||
.Nd CPU performance-monitoring interface
|
||||
.Sh SYNOPSIS
|
||||
.Cd cpu I586_CPU
|
||||
.Cd cpu I686_CPU
|
||||
.Cd options PERFMON
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides access to the internal performance-monitoring
|
||||
capabilities of the
|
||||
.Tn Intel
|
||||
.Tn Pentium
|
||||
and
|
||||
.Tn "Pentium Pro"
|
||||
CPUs.
|
||||
These processors implement two internal counters which can be
|
||||
configured to measure a variety of events for either count or duration
|
||||
(in CPU cycles), as well as a cycle counter which counts clock cycles.
|
||||
The
|
||||
.Nm
|
||||
driver provides a device-style interface to these capabilities.
|
||||
.Pp
|
||||
All access to the performance-monitoring counters is performed through
|
||||
the special device file
|
||||
.Dq Pa /dev/perfmon .
|
||||
This device supports a number of
|
||||
.Xr ioctl 2
|
||||
requests, defined in
|
||||
.In machine/perfmon.h
|
||||
along with the definitions of the various counters for both
|
||||
.Tn Pentium
|
||||
and
|
||||
.Tn "Pentium Pro"
|
||||
processors.
|
||||
.Pp
|
||||
.Sy NOTA BENE :
|
||||
The set of available events differs from processor to processor.
|
||||
It
|
||||
is the responsibility of the programmer to ensure that the event
|
||||
numbers used are the correct ones for the CPU type being measured.
|
||||
.Pp
|
||||
The following
|
||||
.Xr ioctl 2
|
||||
requests are defined:
|
||||
.Bl -tag -width PMIOTSTAMP
|
||||
.It Dv PMIOSETUP
|
||||
.Pq Li "struct pmc"
|
||||
Set up a counter with parameters and flags defined in the structure.
|
||||
The following fields are defined in
|
||||
.Li struct pmc :
|
||||
.Bl -tag -width "u_char pmc_eventx"
|
||||
.It Li "int pmc_num"
|
||||
the number of the counter in question; must be less than
|
||||
.Dv NPMC
|
||||
(currently 2).
|
||||
.It Li "u_char pmc_event"
|
||||
the particular event number to be monitored, as defined in
|
||||
.In machine/perfmon.h .
|
||||
.It Li "u_char pmc_unit"
|
||||
the unit mask value, specific to the event type (see the
|
||||
.Tn Intel
|
||||
documentation).
|
||||
.It Li "u_char pmc_flags"
|
||||
flags modifying the operation of the counter (see below).
|
||||
.It Li "u_char pmc_mask"
|
||||
the counter mask value; essentially, this is a threshold used to
|
||||
restrict the count to events lasting more (or less) than the specified
|
||||
number of clocks.
|
||||
.El
|
||||
.Pp
|
||||
The following
|
||||
.Li pmc_flags
|
||||
values are defined:
|
||||
.Bl -tag -compact -width PMCF_USRxx
|
||||
.It Dv PMCF_USR
|
||||
count events in user mode
|
||||
.It Dv PMCF_OS
|
||||
count events in kernel mode
|
||||
.It Dv PMCF_E
|
||||
count number of events rather than their duration
|
||||
.It Dv PMCF_INV
|
||||
invert the sense of the counter mask comparison
|
||||
.El
|
||||
.It Dv PMIOGET
|
||||
.Pq Li "struct pmc"
|
||||
returns the current configuration of the specified counter.
|
||||
.It Dv PMIOSTART
|
||||
.It Dv PMIOSTOP
|
||||
.Pq Li int
|
||||
starts (stops) the specified counter.
|
||||
Due to hardware deficiencies,
|
||||
counters must be started and stopped in numerical order.
|
||||
(That is to
|
||||
say, counter 0 can never be stopped without first stopping counter 1.)
|
||||
The driver will
|
||||
.Em not
|
||||
enforce this restriction (since it may not be present in future CPUs).
|
||||
.It Dv PMIORESET
|
||||
.Pq Li int
|
||||
reset the specified counter to zero.
|
||||
The counter should be stopped
|
||||
with
|
||||
.Dv PMIOSTOP
|
||||
before it is reset.
|
||||
All counters are automatically reset by
|
||||
.Dv PMIOSETUP .
|
||||
.It Dv PMIOREAD
|
||||
.Pq Li "struct pmc_data"
|
||||
get the current value of the counter.
|
||||
The
|
||||
.Li pmc_data
|
||||
structure defines two fields:
|
||||
.Pp
|
||||
.Bl -tag -compact -width "quad_t pmcd_value"
|
||||
.It Li "int pmcd_num"
|
||||
the number of the counter to read
|
||||
.It Li "quad_t pmcd_value"
|
||||
the resulting value as a 64-bit signed integer
|
||||
.El
|
||||
.Pp
|
||||
In the future, it may be possible to use the
|
||||
.Li RDPMC
|
||||
instruction on
|
||||
.Tn "Pentium Pro"
|
||||
processors to read the counters directly.
|
||||
.It Dv PMIOTSTAMP
|
||||
.Pq Li "struct pmc_tstamp"
|
||||
read the time stamp counter.
|
||||
The
|
||||
.Li pmc_tstamp
|
||||
structure defines two fields:
|
||||
.Pp
|
||||
.Bl -tag -compact -width "quad_t pmct_value"
|
||||
.It Li "int pmct_rate"
|
||||
the approximate rate of the counter, in MHz
|
||||
.It Li "quad_t pmct_value"
|
||||
the current value of the counter as a 64-bit integer
|
||||
.El
|
||||
.Pp
|
||||
It is important to note that the counter rate, as provided in the
|
||||
.Li pmct_rate
|
||||
field, is often incorrect because of calibration difficulties and
|
||||
non-integral clock rates.
|
||||
This field should be considered more of a
|
||||
hint or sanity-check than an actual representation of the rate of
|
||||
clock ticks.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -compact -width "/usr/include/machine/perfmon.h"
|
||||
.It Pa /dev/perfmon
|
||||
character device interface to counters
|
||||
.It Pa /usr/include/machine/perfmon.h
|
||||
include file with definitions of structures and event types
|
||||
.It Pa /usr/share/examples/perfmon
|
||||
sample source code demonstrating use of all the
|
||||
.Fn ioctl
|
||||
commands
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ioctl 2 ,
|
||||
.Xr hwpmc 4
|
||||
.Rs
|
||||
.%A Intel Corporation
|
||||
.%B Pentium Pro Family Developer's Manual
|
||||
.%D January 1996
|
||||
.%V vol. 3
|
||||
.%O Operating System Writer's Manual
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
device first appeared in
|
||||
.Fx 2.2 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Garrett A. Wollman ,
|
||||
MIT Laboratory for Computer Science.
|
||||
@@ -141,10 +141,6 @@ Its frequency can be found using the
|
||||
.Va machdep.tsc_freq
|
||||
sysctl, if it is available.
|
||||
It is used to interpolate between values of the scheduling clock.
|
||||
It can be accessed using the
|
||||
.Dv PMIOTSTAMP
|
||||
request of
|
||||
.Xr perfmon 4 .
|
||||
.It
|
||||
The ACPI clock.
|
||||
This is a real clock/timer with a nominal frequency of 3579545.
|
||||
|
||||
@@ -91,7 +91,6 @@ i386/i386/mp_clock.c optional smp
|
||||
i386/i386/mp_machdep.c optional smp
|
||||
i386/i386/mpboot.S optional smp
|
||||
i386/i386/npx.c standard
|
||||
i386/i386/perfmon.c optional perfmon
|
||||
i386/i386/pmap_base.c standard
|
||||
i386/i386/pmap_nopae.c standard
|
||||
i386/i386/pmap_pae.c standard
|
||||
|
||||
@@ -177,12 +177,6 @@ options CYRIX_CACHE_REALLY_WORKS
|
||||
# Debug options
|
||||
options NPX_DEBUG # enable npx debugging
|
||||
|
||||
#
|
||||
# PERFMON causes the driver for Pentium/Pentium Pro performance counters
|
||||
# to be compiled. See perfmon(4) for more information.
|
||||
#
|
||||
options PERFMON
|
||||
|
||||
#
|
||||
# Hints for the non-optional Numeric Processing eXtension driver.
|
||||
envvar hint.npx.0.flags="0x0"
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "opt_isa.h"
|
||||
#include "opt_kstack_pages.h"
|
||||
#include "opt_maxmem.h"
|
||||
#include "opt_perfmon.h"
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@@ -133,9 +132,6 @@
|
||||
#include <x86/ucode.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <x86/init.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
#ifdef SMP
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
@@ -245,9 +241,6 @@ cpu_startup(void *dummy)
|
||||
startrtclock();
|
||||
printcpuinfo();
|
||||
panicifcpuunsupported();
|
||||
#ifdef PERFMON
|
||||
perfmon_init();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Display physical memory if SMBIOS reports reasonable amount.
|
||||
|
||||
@@ -1,402 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#ifndef SMP
|
||||
#include <machine/cputypes.h>
|
||||
#endif
|
||||
#include <machine/clock.h>
|
||||
#include <machine/perfmon.h>
|
||||
#include <machine/specialreg.h>
|
||||
|
||||
static int perfmon_inuse;
|
||||
static int perfmon_cpuok;
|
||||
#ifndef SMP
|
||||
static int msr_ctl[NPMC];
|
||||
#endif
|
||||
static int msr_pmc[NPMC];
|
||||
static unsigned int ctl_shadow[NPMC];
|
||||
static quad_t pmc_shadow[NPMC]; /* used when ctr is stopped on P5 */
|
||||
static int (*writectl)(int);
|
||||
#ifndef SMP
|
||||
static int writectl5(int);
|
||||
static int writectl6(int);
|
||||
#endif
|
||||
|
||||
static d_close_t perfmon_close;
|
||||
static d_open_t perfmon_open;
|
||||
static d_ioctl_t perfmon_ioctl;
|
||||
|
||||
/*
|
||||
* XXX perfmon_init_dev(void *) is a split from the perfmon_init() function.
|
||||
* This solves a problem for DEVFS users. It loads the "perfmon" driver after
|
||||
* the DEVFS subsystem has been kicked into action. The SI_ORDER_ANY is to
|
||||
* assure that it is the most lowest priority task which, guarantees the
|
||||
* above.
|
||||
*/
|
||||
static void perfmon_init_dev(void *);
|
||||
SYSINIT(cpu, SI_SUB_DRIVERS, SI_ORDER_ANY, perfmon_init_dev, NULL);
|
||||
|
||||
static struct cdevsw perfmon_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_open = perfmon_open,
|
||||
.d_close = perfmon_close,
|
||||
.d_ioctl = perfmon_ioctl,
|
||||
.d_name = "perfmon",
|
||||
};
|
||||
|
||||
/*
|
||||
* Must be called after cpu_class is set up.
|
||||
*/
|
||||
void
|
||||
perfmon_init(void)
|
||||
{
|
||||
#ifndef SMP
|
||||
switch(cpu_class) {
|
||||
case CPUCLASS_586:
|
||||
perfmon_cpuok = 1;
|
||||
msr_ctl[0] = MSR_P5_CESR;
|
||||
msr_ctl[1] = MSR_P5_CESR;
|
||||
msr_pmc[0] = MSR_P5_CTR0;
|
||||
msr_pmc[1] = MSR_P5_CTR1;
|
||||
writectl = writectl5;
|
||||
break;
|
||||
case CPUCLASS_686:
|
||||
perfmon_cpuok = 1;
|
||||
msr_ctl[0] = MSR_EVNTSEL0;
|
||||
msr_ctl[1] = MSR_EVNTSEL1;
|
||||
msr_pmc[0] = MSR_PERFCTR0;
|
||||
msr_pmc[1] = MSR_PERFCTR1;
|
||||
writectl = writectl6;
|
||||
break;
|
||||
|
||||
default:
|
||||
perfmon_cpuok = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* SMP */
|
||||
}
|
||||
|
||||
static void
|
||||
perfmon_init_dev(void *dummy)
|
||||
{
|
||||
make_dev(&perfmon_cdevsw, 32, UID_ROOT, GID_KMEM, 0640, "perfmon");
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_avail(void)
|
||||
{
|
||||
return perfmon_cpuok;
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_setup(int pmc, unsigned int control)
|
||||
{
|
||||
register_t saveintr;
|
||||
|
||||
if (pmc < 0 || pmc >= NPMC)
|
||||
return EINVAL;
|
||||
|
||||
perfmon_inuse |= (1 << pmc);
|
||||
control &= ~(PMCF_SYS_FLAGS << 16);
|
||||
saveintr = intr_disable();
|
||||
ctl_shadow[pmc] = control;
|
||||
writectl(pmc);
|
||||
wrmsr(msr_pmc[pmc], pmc_shadow[pmc] = 0);
|
||||
intr_restore(saveintr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_get(int pmc, unsigned int *control)
|
||||
{
|
||||
if (pmc < 0 || pmc >= NPMC)
|
||||
return EINVAL;
|
||||
|
||||
if (perfmon_inuse & (1 << pmc)) {
|
||||
*control = ctl_shadow[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);
|
||||
ctl_shadow[pmc] = 0;
|
||||
perfmon_inuse &= ~(1 << pmc);
|
||||
return 0;
|
||||
}
|
||||
return EBUSY; /* XXX reversed sense */
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_start(int pmc)
|
||||
{
|
||||
register_t saveintr;
|
||||
|
||||
if (pmc < 0 || pmc >= NPMC)
|
||||
return EINVAL;
|
||||
|
||||
if (perfmon_inuse & (1 << pmc)) {
|
||||
saveintr = intr_disable();
|
||||
ctl_shadow[pmc] |= (PMCF_EN << 16);
|
||||
wrmsr(msr_pmc[pmc], pmc_shadow[pmc]);
|
||||
writectl(pmc);
|
||||
intr_restore(saveintr);
|
||||
return 0;
|
||||
}
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_stop(int pmc)
|
||||
{
|
||||
register_t saveintr;
|
||||
|
||||
if (pmc < 0 || pmc >= NPMC)
|
||||
return EINVAL;
|
||||
|
||||
if (perfmon_inuse & (1 << pmc)) {
|
||||
saveintr = intr_disable();
|
||||
pmc_shadow[pmc] = rdmsr(msr_pmc[pmc]) & 0xffffffffffULL;
|
||||
ctl_shadow[pmc] &= ~(PMCF_EN << 16);
|
||||
writectl(pmc);
|
||||
intr_restore(saveintr);
|
||||
return 0;
|
||||
}
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
int
|
||||
perfmon_read(int pmc, quad_t *val)
|
||||
{
|
||||
if (pmc < 0 || pmc >= NPMC)
|
||||
return EINVAL;
|
||||
|
||||
if (perfmon_inuse & (1 << pmc)) {
|
||||
if (ctl_shadow[pmc] & (PMCF_EN << 16))
|
||||
*val = rdmsr(msr_pmc[pmc]) & 0xffffffffffULL;
|
||||
else
|
||||
*val = pmc_shadow[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], pmc_shadow[pmc] = 0);
|
||||
return 0;
|
||||
}
|
||||
return EBUSY;
|
||||
}
|
||||
|
||||
#ifndef SMP
|
||||
/*
|
||||
* Unfortunately, the performance-monitoring registers are laid out
|
||||
* differently in the P5 and P6. We keep everything in P6 format
|
||||
* internally (except for the event code), and convert to P5
|
||||
* format as needed on those CPUs. The writectl function pointer
|
||||
* is set up to point to one of these functions by perfmon_init().
|
||||
*/
|
||||
int
|
||||
writectl6(int pmc)
|
||||
{
|
||||
if (pmc > 0 && !(ctl_shadow[pmc] & (PMCF_EN << 16))) {
|
||||
wrmsr(msr_ctl[pmc], 0);
|
||||
} else {
|
||||
wrmsr(msr_ctl[pmc], ctl_shadow[pmc]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define P5FLAG_P 0x200
|
||||
#define P5FLAG_E 0x100
|
||||
#define P5FLAG_USR 0x80
|
||||
#define P5FLAG_OS 0x40
|
||||
|
||||
int
|
||||
writectl5(int pmc)
|
||||
{
|
||||
quad_t newval = 0;
|
||||
|
||||
if (ctl_shadow[1] & (PMCF_EN << 16)) {
|
||||
if (ctl_shadow[1] & (PMCF_USR << 16))
|
||||
newval |= P5FLAG_USR << 16;
|
||||
if (ctl_shadow[1] & (PMCF_OS << 16))
|
||||
newval |= P5FLAG_OS << 16;
|
||||
if (!(ctl_shadow[1] & (PMCF_E << 16)))
|
||||
newval |= P5FLAG_E << 16;
|
||||
newval |= (ctl_shadow[1] & 0x3f) << 16;
|
||||
}
|
||||
if (ctl_shadow[0] & (PMCF_EN << 16)) {
|
||||
if (ctl_shadow[0] & (PMCF_USR << 16))
|
||||
newval |= P5FLAG_USR;
|
||||
if (ctl_shadow[0] & (PMCF_OS << 16))
|
||||
newval |= P5FLAG_OS;
|
||||
if (!(ctl_shadow[0] & (PMCF_E << 16)))
|
||||
newval |= P5FLAG_E;
|
||||
newval |= ctl_shadow[0] & 0x3f;
|
||||
}
|
||||
|
||||
wrmsr(msr_ctl[0], newval);
|
||||
return 0; /* XXX should check for unimplemented bits */
|
||||
}
|
||||
#endif /* !SMP */
|
||||
|
||||
/*
|
||||
* Now the user-mode interface, called from a subdevice of mem.c.
|
||||
*/
|
||||
static int writer;
|
||||
static int writerpmc;
|
||||
|
||||
static int
|
||||
perfmon_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
if (!perfmon_cpuok)
|
||||
return ENXIO;
|
||||
|
||||
if (flags & FWRITE) {
|
||||
if (writer) {
|
||||
return EBUSY;
|
||||
} else {
|
||||
writer = 1;
|
||||
writerpmc = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
perfmon_close(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
if (flags & FWRITE) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NPMC; i++) {
|
||||
if (writerpmc & (1 << i))
|
||||
perfmon_fini(i);
|
||||
}
|
||||
writer = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
perfmon_ioctl(struct cdev *dev, u_long cmd, caddr_t param, int flags, struct thread *td)
|
||||
{
|
||||
struct pmc *pmc;
|
||||
struct pmc_data *pmcd;
|
||||
struct pmc_tstamp *pmct;
|
||||
uint64_t freq;
|
||||
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:
|
||||
freq = atomic_load_acq_64(&tsc_freq);
|
||||
if (freq == 0) {
|
||||
rv = ENOTTY;
|
||||
break;
|
||||
}
|
||||
pmct = (struct pmc_tstamp *)param;
|
||||
/* XXX interface loses precision. */
|
||||
pmct->pmct_rate = freq / 1000000;
|
||||
pmct->pmct_value = rdtsc();
|
||||
rv = 0;
|
||||
break;
|
||||
default:
|
||||
rv = ENOTTY;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Interface to performance-monitoring counters for Intel Pentium and
|
||||
* Pentium Pro CPUs.
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_PERFMON_H_
|
||||
#define _MACHINE_PERFMON_H_
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#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(void);
|
||||
int perfmon_avail(void);
|
||||
int perfmon_setup(int, unsigned int);
|
||||
int perfmon_get(int, unsigned int *);
|
||||
int perfmon_fini(int);
|
||||
int perfmon_start(int);
|
||||
int perfmon_stop(int);
|
||||
int perfmon_read(int, quad_t *);
|
||||
int perfmon_reset(int);
|
||||
|
||||
#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_ */
|
||||
@@ -1822,9 +1822,6 @@ OLD_FILES+=usr/share/examples/netgraph/virtual.chain
|
||||
OLD_FILES+=usr/share/examples/netgraph/virtual.lan
|
||||
OLD_FILES+=usr/share/examples/oci/Containerfile.pkg
|
||||
OLD_FILES+=usr/share/examples/oci/README
|
||||
OLD_FILES+=usr/share/examples/perfmon/Makefile
|
||||
OLD_FILES+=usr/share/examples/perfmon/README
|
||||
OLD_FILES+=usr/share/examples/perfmon/perfmon.c
|
||||
OLD_FILES+=usr/share/examples/pf/ackpri
|
||||
OLD_FILES+=usr/share/examples/pf/faq-example1
|
||||
OLD_FILES+=usr/share/examples/pf/faq-example2
|
||||
@@ -1991,7 +1988,6 @@ OLD_DIRS+=usr/share/examples/libvgl
|
||||
OLD_DIRS+=usr/share/examples/mdoc
|
||||
OLD_DIRS+=usr/share/examples/netgraph
|
||||
OLD_DIRS+=usr/share/examples/oci
|
||||
OLD_DIRS+=usr/share/examples/perfmon
|
||||
OLD_DIRS+=usr/share/examples/pf
|
||||
OLD_DIRS+=usr/share/examples/ppi
|
||||
OLD_DIRS+=usr/share/examples/ppp
|
||||
|
||||
Reference in New Issue
Block a user