aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mashtizadeh <ali@mashtizadeh.com>2026-04-20 22:06:30 +0000
committerWarner Losh <imp@FreeBSD.org>2026-04-24 16:23:05 +0000
commit70ae0c4524d2c5d0aae3339e95f6bd4f3c480b6e (patch)
treef341673e612b18b5103446e61530bc27bcd59e65
parent576c6e9620dff3e92f3c5d1e5be4d92c9eb29828 (diff)
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
-rw-r--r--ObsoleteFiles.inc8
-rw-r--r--etc/mtree/BSD.usr.dist2
-rw-r--r--share/examples/Makefile7
-rw-r--r--share/examples/perfmon/Makefile8
-rw-r--r--share/examples/perfmon/README23
-rw-r--r--share/examples/perfmon/perfmon.c191
-rw-r--r--share/man/man4/man4.i386/Makefile1
-rw-r--r--share/man/man4/man4.i386/perfmon.4211
-rw-r--r--share/man/man7/clocks.74
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/i386/conf/NOTES6
-rw-r--r--sys/i386/i386/machdep.c7
-rw-r--r--sys/i386/i386/perfmon.c402
-rw-r--r--sys/i386/include/perfmon.h253
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc4
15 files changed, 8 insertions, 1120 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index a4fdac95bf5a..465508bf40a3 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -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
diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist
index b281a368861d..120b961d230c 100644
--- a/etc/mtree/BSD.usr.dist
+++ b/etc/mtree/BSD.usr.dist
@@ -346,8 +346,6 @@
..
netgraph
..
- perfmon
- ..
pf
..
ppi
diff --git a/share/examples/Makefile b/share/examples/Makefile
index d977f2e5a0da..dae84f27d9dc 100644
--- a/share/examples/Makefile
+++ b/share/examples/Makefile
@@ -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"
diff --git a/share/examples/perfmon/Makefile b/share/examples/perfmon/Makefile
deleted file mode 100644
index 96712dee88e3..000000000000
--- a/share/examples/perfmon/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PACKAGE=examples
-FILESDIR=${SHAREDIR}/examples/${PROG}
-PROG= perfmon
-MAN=
-
-install:
-
-.include <bsd.prog.mk>
diff --git a/share/examples/perfmon/README b/share/examples/perfmon/README
deleted file mode 100644
index 25452813f3db..000000000000
--- a/share/examples/perfmon/README
+++ /dev/null
@@ -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).
diff --git a/share/examples/perfmon/perfmon.c b/share/examples/perfmon/perfmon.c
deleted file mode 100644
index 1b7afad9d69e..000000000000
--- a/share/examples/perfmon/perfmon.c
+++ /dev/null
@@ -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);
-}
diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile
index ad9b3a01828c..1136de341947 100644
--- a/share/man/man4/man4.i386/Makefile
+++ b/share/man/man4/man4.i386/Makefile
@@ -6,7 +6,6 @@ MAN= apm.4 \
npx.4 \
pae.4 \
pbio.4 \
- perfmon.4 \
pnp.4 \
pnpbios.4 \
sbni.4 \
diff --git a/share/man/man4/man4.i386/perfmon.4 b/share/man/man4/man4.i386/perfmon.4
deleted file mode 100644
index 7a899e863f1b..000000000000
--- a/share/man/man4/man4.i386/perfmon.4
+++ /dev/null
@@ -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.
diff --git a/share/man/man7/clocks.7 b/share/man/man7/clocks.7
index 3a218f844450..26283909f06d 100644
--- a/share/man/man7/clocks.7
+++ b/share/man/man7/clocks.7
@@ -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.
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index e6c2089e2c1e..0e7a1f24be7e 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -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
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index fbcea76527db..25bfb99c1fef 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -178,12 +178,6 @@ options CYRIX_CACHE_REALLY_WORKS
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"
envvar hint.npx.0.irq="13"
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 7dbaded419e6..f9afb9afe45f 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -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.
diff --git a/sys/i386/i386/perfmon.c b/sys/i386/i386/perfmon.c
deleted file mode 100644
index 5e6d37d7f5ed..000000000000
--- a/sys/i386/i386/perfmon.c
+++ /dev/null
@@ -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;
-}
diff --git a/sys/i386/include/perfmon.h b/sys/i386/include/perfmon.h
deleted file mode 100644
index c23498aeace4..000000000000
--- a/sys/i386/include/perfmon.h
+++ /dev/null
@@ -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_ */
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index a4ddf8dbf51f..35ee7d094240 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -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