summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-01-30 23:58:04 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-01-30 23:58:04 +0000
commita2200f32d895069d3019e8c336d4eb3482b408b1 (patch)
tree8c8e713c469d515368b64d70f089fbb32452eaeb /sys/arch/sparc64
parentf4ca009318dd00a3457741ce99764a6ba3d19a3e (diff)
Driver for getting at performance counters. These manifest them
selves as "sc at sbus" and a couple of registers on psycho (sabre doesn't appear to have these registers).
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/conf/GENERIC6
-rw-r--r--sys/arch/sparc64/conf/files.sparc649
-rw-r--r--sys/arch/sparc64/dev/psycho.c17
-rw-r--r--sys/arch/sparc64/dev/psychoreg.h35
-rw-r--r--sys/arch/sparc64/dev/uperf.c204
-rw-r--r--sys/arch/sparc64/dev/uperf_psycho.c195
-rw-r--r--sys/arch/sparc64/dev/uperf_psychovar.h37
-rw-r--r--sys/arch/sparc64/dev/uperfvar.h120
-rw-r--r--sys/arch/sparc64/include/conf.h12
-rw-r--r--sys/arch/sparc64/sparc64/conf.c5
10 files changed, 633 insertions, 7 deletions
diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC
index aff5f65ca92..0945a81b20b 100644
--- a/sys/arch/sparc64/conf/GENERIC
+++ b/sys/arch/sparc64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.45 2002/01/28 19:45:15 jason Exp $
+# $OpenBSD: GENERIC,v 1.46 2002/01/30 23:58:02 jason Exp $
# $NetBSD: GENERIC32,v 1.18 2001/07/20 00:07:12 eeh Exp $
machine sparc64
@@ -27,6 +27,8 @@ pci* at ppb?
ppb* at pci? dev ? function ?
ebus* at pci?
+uperf* at psycho?
+
# PCI Ethernet
hme* at pci? dev ? function ?
gem* at pci? dev ? function ?
@@ -80,6 +82,8 @@ wskbd* at comkbd?
audioce* at ebus?
audio* at audioce?
+uperf* at sbus? slot ? offset ?
+
zs* at sbus? slot ? offset ?
zstty* at zs? channel ?
zskbd* at zs? channel ?
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index 93faaa99637..0740fe73d3d 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.27 2002/01/25 03:24:53 jason Exp $
+# $OpenBSD: files.sparc64,v 1.28 2002/01/30 23:58:02 jason Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -18,6 +18,9 @@ file arch/sparc64/dev/pcons.c pcons needs-flag
device hme: ether, ifnet, mii, ifmedia
file dev/ic/hme.c hme
+device uperf
+file arch/sparc64/dev/uperf.c uperf needs-flag
+
include "dev/sun/files.sun"
include "dev/wscons/files.wscons"
include "dev/sbus/files.sbus"
@@ -33,12 +36,16 @@ file arch/sparc64/sparc64/netbsd_machdep.c compat_netbsd
attach sbus at mainbus
file arch/sparc64/dev/sbus.c sbus
+define psycho {}
device psycho: pcibus
attach psycho at mainbus
include "dev/pci/files.pci"
file arch/sparc64/dev/psycho.c psycho
file arch/sparc64/dev/pci_machdep.c psycho
+attach uperf at psycho with uperf_psycho
+file arch/sparc64/dev/uperf_psycho.c uperf_psycho needs-flag
+
attach hme at pci with hme_pci
file dev/pci/if_hme_pci.c hme_pci
diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c
index d5aa5bf43f5..36692e94026 100644
--- a/sys/arch/sparc64/dev/psycho.c
+++ b/sys/arch/sparc64/dev/psycho.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: psycho.c,v 1.11 2002/01/29 20:33:19 jason Exp $ */
+/* $OpenBSD: psycho.c,v 1.12 2002/01/30 23:58:02 jason Exp $ */
/* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */
/*
@@ -34,6 +34,8 @@
* UltraSPARC IIi and IIe `sabre' PCI controllers.
*/
+#include "uperf_psycho.h"
+
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
@@ -55,6 +57,9 @@
#include <sparc64/dev/iommuvar.h>
#include <sparc64/dev/psychoreg.h>
#include <sparc64/dev/psychovar.h>
+#if NUPERF_PSYCHO > 0
+#include <sparc64/dev/uperf_psychovar.h>
+#endif
#include <sparc64/sparc64/cache.h>
#undef DEBUG
@@ -410,6 +415,16 @@ psycho_attach(parent, self, aux)
* arrive here, start up the IOMMU and get a config space tag.
*/
if (osc == NULL) {
+#if NUPERF_PSYCHO > 0
+ if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
+ struct uperf_psycho_attach_args upaa;
+
+ upaa.upaa_name = "uperf";
+ upaa.upaa_regs = &sc->sc_regs->psy_pm;
+
+ (void)config_found(self, &upaa, psycho_print);
+ }
+#endif
/*
* Establish handlers for interesting interrupts....
diff --git a/sys/arch/sparc64/dev/psychoreg.h b/sys/arch/sparc64/dev/psychoreg.h
index 2eaa0ac2785..d28b225e800 100644
--- a/sys/arch/sparc64/dev/psychoreg.h
+++ b/sys/arch/sparc64/dev/psychoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: psychoreg.h,v 1.7 2002/01/25 23:51:04 jason Exp $ */
+/* $OpenBSD: psychoreg.h,v 1.8 2002/01/30 23:58:02 jason Exp $ */
/* $NetBSD: psychoreg.h,v 1.6.4.2 2001/09/13 01:14:40 thorpej Exp $ */
/*
@@ -312,6 +312,39 @@ struct psychoreg {
#define PSY_PCIAFSR_MID 0x000000003e000000 /* mid causing error */
#define PSY_PCIAFSR_RESV3 0x0000000001ffffff /* reserved */
+/* performance counter control */
+#define PSY_PMCR_CLR1 0x0000000000008000 /* clear cnt 1 */
+#define PSY_PMCR_SEL1 0x0000000000001f00 /* set cnt 1 src */
+#define PSY_PMCR_CLR0 0x0000000000000080 /* clear cnt 0 */
+#define PSY_PMCR_SEL0 0x000000000000001f /* set cnt 0 src */
+
+#define PSY_PMCRSEL_SDVRA 0x0000000000000000 /* stream dvma read, A */
+#define PSY_PMCRSEL_SDVWA 0x0000000000000001 /* stream dvma write, A */
+#define PSY_PMCRSEL_CDVRA 0x0000000000000002 /* consist dvma read, A */
+#define PSY_PMCRSEL_CDVWA 0x0000000000000003 /* consist dvma write, A */
+#define PSY_PMCRSEL_SBMA 0x0000000000000004 /* stream buf miss, A */
+#define PSY_PMCRSEL_DVA 0x0000000000000005 /* dvma cycles, A */
+#define PSY_PMCRSEL_DVWA 0x0000000000000006 /* dvma words, A */
+#define PSY_PMCRSEL_PIOA 0x0000000000000007 /* pio cycles, A */
+#define PSY_PMCRSEL_SDVRB 0x0000000000000008 /* stream dvma read, B */
+#define PSY_PMCRSEL_SDVWB 0x0000000000000009 /* stream dvma write, B */
+#define PSY_PMCRSEL_CDVRB 0x000000000000000a /* consist dvma read, B */
+#define PSY_PMCRSEL_CDVWB 0x000000000000000b /* consist dvma write, B */
+#define PSY_PMCRSEL_SBMB 0x000000000000000c /* stream buf miss, B */
+#define PSY_PMCRSEL_DVB 0x000000000000000d /* dvma cycles, B */
+#define PSY_PMCRSEL_DVWB 0x000000000000000e /* dvma words, B */
+#define PSY_PMCRSEL_PIOB 0x000000000000000f /* pio cycles, B */
+#define PSY_PMCRSEL_TLBMISS 0x0000000000000010 /* tlb misses */
+#define PSY_PMCRSEL_NINTRS 0x0000000000000011 /* interrupts */
+#define PSY_PMCRSEL_INACK 0x0000000000000012 /* intr nacks */
+#define PSY_PMCRSEL_PIOR 0x0000000000000013 /* pio read xfers */
+#define PSY_PMCRSEL_PIOW 0x0000000000000014 /* pio write xfers */
+#define PSY_PMCRSEL_MERGE 0x0000000000000015 /* merge buffer xacts */
+#define PSY_PMCRSEL_TBLA 0x0000000000000016 /* tbl walk retries, A */
+#define PSY_PMCRSEL_STCA 0x0000000000000017 /* stc retries, A */
+#define PSY_PMCRSEL_TBLB 0x0000000000000018 /* tbl walk retries, B */
+#define PSY_PMCRSEL_STCB 0x0000000000000019 /* stc retries, B */
+
/*
* these are the PROM structures we grovel
*/
diff --git a/sys/arch/sparc64/dev/uperf.c b/sys/arch/sparc64/dev/uperf.c
new file mode 100644
index 00000000000..01b03f6f469
--- /dev/null
+++ b/sys/arch/sparc64/dev/uperf.c
@@ -0,0 +1,204 @@
+/* $OpenBSD: uperf.c,v 1.1 2002/01/30 23:58:02 jason Exp $ */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/ioctl.h>
+#include <sys/conf.h>
+
+#include <machine/conf.h>
+
+#include <arch/sparc64/dev/uperfvar.h>
+
+struct cfdriver uperf_cd = {
+ NULL, "uperf", DV_DULL
+};
+
+int uperf_getcntsrc __P((struct uperf_softc *, struct uperf_io *));
+int uperf_findbyval __P((struct uperf_softc *, int, u_int, int *));
+int uperf_findbysrc __P((struct uperf_softc *, int, int, u_int32_t *));
+int uperf_setcntsrc __P((struct uperf_softc *, struct uperf_io *));
+
+int
+uperfopen(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ if (minor(dev) >= uperf_cd.cd_ndevs)
+ return (ENXIO);
+ if (uperf_cd.cd_devs[minor(dev)] == NULL)
+ return (ENXIO);
+ return (0);
+}
+
+int
+uperfclose(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ return (0);
+}
+
+int
+uperfioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ struct uperf_softc *usc = uperf_cd.cd_devs[minor(dev)];
+ struct uperf_io *io = (struct uperf_io *)data;
+ int error = EINVAL;
+
+ switch (cmd) {
+ case UPIO_GCNTSRC:
+ error = uperf_getcntsrc(usc, io);
+ break;
+ case UPIO_SCNTSRC:
+ error = uperf_setcntsrc(usc, io);
+ break;
+ case UPIO_CLRCNT:
+ error = usc->usc_clrcnt(usc->usc_cookie, io->cnt_flags);
+ break;
+ case UPIO_GETCNT:
+ error = usc->usc_getcnt(usc->usc_cookie, io->cnt_flags,
+ &io->cnt_val0, &io->cnt_val1);
+ break;
+ }
+
+ return (error);
+}
+
+int
+uperf_getcntsrc(usc, io)
+ struct uperf_softc *usc;
+ struct uperf_io *io;
+{
+ u_int cnt0_src, cnt1_src;
+ int error;
+
+ error = usc->usc_getcntsrc(usc->usc_cookie, io->cnt_flags,
+ &cnt0_src, &cnt1_src);
+ if (error)
+ return (error);
+
+ if (io->cnt_flags & UPERF_CNT0) {
+ error = uperf_findbyval(usc, UPERF_CNT0,
+ cnt0_src, &io->cnt_src0);
+ if (error)
+ return (error);
+ }
+
+ if (io->cnt_flags & UPERF_CNT1) {
+ error = uperf_findbyval(usc, UPERF_CNT1,
+ cnt1_src, &io->cnt_src1);
+ if (error)
+ return (error);
+ }
+ return (0);
+}
+
+int
+uperf_findbyval(usc, cnt, uval, rval)
+ struct uperf_softc *usc;
+ int cnt;
+ u_int uval;
+ int *rval;
+{
+ struct uperf_src *srcs = usc->usc_srcs;
+
+ if (srcs->us_src == NULL)
+ return (EINVAL);
+
+ while (srcs->us_src != -1) {
+ if (srcs->us_val == uval && srcs->us_flags & cnt) {
+ *rval = srcs->us_src;
+ return (0);
+ }
+ srcs++;
+ }
+ return (EINVAL);
+}
+
+int
+uperf_setcntsrc(usc, io)
+ struct uperf_softc *usc;
+ struct uperf_io *io;
+{
+ u_int32_t cnt0_src, cnt1_src;
+ int error;
+
+ if (io->cnt_flags & UPERF_CNT0) {
+ error = uperf_findbysrc(usc, UPERF_CNT0,
+ io->cnt_src0, &cnt0_src);
+ if (error)
+ return (error);
+ }
+ if (io->cnt_flags & UPERF_CNT1) {
+ error = uperf_findbysrc(usc, UPERF_CNT1,
+ io->cnt_src1, &cnt1_src);
+ if (error)
+ return (error);
+ }
+ return ((usc->usc_setcntsrc)(usc->usc_cookie, io->cnt_flags,
+ cnt0_src, cnt1_src));
+}
+
+int
+uperf_findbysrc(usc, cnt, src, rval)
+ struct uperf_softc *usc;
+ int cnt, src;
+ u_int32_t *rval;
+{
+ struct uperf_src *srcs = usc->usc_srcs;
+
+ if (srcs->us_src == NULL)
+ return (EINVAL);
+
+ while (srcs->us_src != -1) {
+ if (srcs->us_src == src && srcs->us_flags & cnt) {
+ *rval = srcs->us_val;
+ return (0);
+ }
+ srcs++;
+ }
+ return (EINVAL);
+}
diff --git a/sys/arch/sparc64/dev/uperf_psycho.c b/sys/arch/sparc64/dev/uperf_psycho.c
new file mode 100644
index 00000000000..43ef46aa6f3
--- /dev/null
+++ b/sys/arch/sparc64/dev/uperf_psycho.c
@@ -0,0 +1,195 @@
+/* $OpenBSD: uperf_psycho.c,v 1.1 2002/01/30 23:58:02 jason Exp $ */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/autoconf.h>
+
+#include <arch/sparc64/dev/iommureg.h>
+#include <arch/sparc64/dev/psychoreg.h>
+#include <arch/sparc64/dev/uperfvar.h>
+#include <arch/sparc64/dev/uperf_psychovar.h>
+
+int uperf_psycho_match __P((struct device *, void *, void *));
+void uperf_psycho_attach __P((struct device *, struct device *, void *));
+
+struct uperf_psycho_softc {
+ struct uperf_softc sc_usc;
+ struct perfmon *sc_pm;
+};
+
+struct cfattach uperf_psycho_ca = {
+ sizeof(struct uperf_psycho_softc), uperf_psycho_match, uperf_psycho_attach
+};
+
+int uperf_psycho_getcnt __P((void *, int, u_int32_t *, u_int32_t *));
+int uperf_psycho_clrcnt __P((void *, int));
+int uperf_psycho_getcntsrc __P((void *, int, u_int *, u_int *));
+int uperf_psycho_setcntsrc __P((void *, int, u_int, u_int));
+
+struct uperf_src uperf_psycho_srcs[] = {
+ { UPERFSRC_SDVRA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SDVRA },
+ { UPERFSRC_SDVWA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SDVWA },
+ { UPERFSRC_CDVRA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_CDVRA },
+ { UPERFSRC_CDVWA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_CDVWA },
+ { UPERFSRC_SBMA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SBMA },
+ { UPERFSRC_DVA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_DVA },
+ { UPERFSRC_DVWA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_DVWA },
+ { UPERFSRC_PIOA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_PIOA },
+ { UPERFSRC_SDVRB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SDVRB },
+ { UPERFSRC_SDVWB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SDVWB },
+ { UPERFSRC_CDVRB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_CDVRB },
+ { UPERFSRC_CDVWB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_CDVWB },
+ { UPERFSRC_SBMB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_SBMB },
+ { UPERFSRC_DVB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_DVB },
+ { UPERFSRC_DVWB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_DVWB },
+ { UPERFSRC_PIOB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_PIOB },
+ { UPERFSRC_TLBMISS, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_TLBMISS },
+ { UPERFSRC_NINTRS, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_NINTRS },
+ { UPERFSRC_INACK, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_INACK },
+ { UPERFSRC_PIOR, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_PIOR },
+ { UPERFSRC_PIOW, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_PIOW },
+ { UPERFSRC_MERGE, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_MERGE },
+ { UPERFSRC_TBLA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_TBLA },
+ { UPERFSRC_STCA, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_STCA },
+ { UPERFSRC_TBLB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_TBLB },
+ { UPERFSRC_STCB, UPERF_CNT0|UPERF_CNT1, PSY_PMCRSEL_STCB },
+ { -1, -1, 0 }
+};
+
+int
+uperf_psycho_match(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct uperf_psycho_attach_args *upaa = aux;
+
+ return (strcmp(upaa->upaa_name, "uperf") == 0);
+}
+
+void
+uperf_psycho_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct uperf_psycho_attach_args *upaa = aux;
+ struct uperf_psycho_softc *sc = (struct uperf_psycho_softc *)self;
+
+ sc->sc_pm = upaa->upaa_regs;
+ sc->sc_usc.usc_cookie = sc;
+ sc->sc_usc.usc_getcntsrc = uperf_psycho_getcntsrc;
+ sc->sc_usc.usc_setcntsrc = uperf_psycho_setcntsrc;
+ sc->sc_usc.usc_clrcnt = uperf_psycho_clrcnt;
+ sc->sc_usc.usc_getcnt = uperf_psycho_getcnt;
+ sc->sc_usc.usc_srcs = uperf_psycho_srcs;
+
+ printf("\n");
+}
+
+int
+uperf_psycho_clrcnt(vsc, flags)
+ void *vsc;
+ int flags;
+{
+ struct uperf_psycho_softc *sc = vsc;
+ u_int64_t cr = sc->sc_pm->pm_cr;
+
+ if (flags & UPERF_CNT0)
+ cr |= PSY_PMCR_CLR0;
+ if (flags & UPERF_CNT1)
+ cr |= PSY_PMCR_CLR1;
+ sc->sc_pm->pm_cr = cr;
+ return (0);
+}
+
+int
+uperf_psycho_setcntsrc(vsc, flags, src0, src1)
+ void *vsc;
+ int flags;
+ u_int src0, src1;
+{
+ struct uperf_psycho_softc *sc = vsc;
+ u_int64_t cr = sc->sc_pm->pm_cr;
+
+ if (flags & UPERF_CNT0) {
+ cr &= ~PSY_PMCR_SEL0;
+ cr |= ((src0 << 0) & PSY_PMCR_SEL0) | PSY_PMCR_CLR0;
+ }
+ if (flags & UPERF_CNT1) {
+ cr &= ~PSY_PMCR_SEL1;
+ cr |= ((src1 << 8) & PSY_PMCR_SEL1) | PSY_PMCR_CLR1;
+ }
+ sc->sc_pm->pm_cr = cr;
+ cr = sc->sc_pm->pm_cr;
+ return (0);
+}
+
+int
+uperf_psycho_getcntsrc(vsc, flags, srcp0, srcp1)
+ void *vsc;
+ int flags;
+ u_int *srcp0, *srcp1;
+{
+ struct uperf_psycho_softc *sc = vsc;
+ u_int64_t cr = sc->sc_pm->pm_cr;
+
+ if (flags & UPERF_CNT0)
+ *srcp0 = (cr & PSY_PMCR_SEL0) >> 0;
+ if (flags & UPERF_CNT1)
+ *srcp1 = (cr & PSY_PMCR_SEL1) >> 8;
+ return (0);
+}
+
+int
+uperf_psycho_getcnt(vsc, flags, cntp0, cntp1)
+ void *vsc;
+ int flags;
+ u_int32_t *cntp0, *cntp1;
+{
+ struct uperf_psycho_softc *sc = vsc;
+ u_int64_t cnt = sc->sc_pm->pm_count;
+
+ if (flags & UPERF_CNT0)
+ *cntp0 = (cnt >> 32) & 0xffffffff;
+ if (flags & UPERF_CNT1)
+ *cntp1 = (cnt >> 0) & 0xffffffff;
+ return (0);
+}
diff --git a/sys/arch/sparc64/dev/uperf_psychovar.h b/sys/arch/sparc64/dev/uperf_psychovar.h
new file mode 100644
index 00000000000..835ccf0a759
--- /dev/null
+++ b/sys/arch/sparc64/dev/uperf_psychovar.h
@@ -0,0 +1,37 @@
+/* $OpenBSD: uperf_psychovar.h,v 1.1 2002/01/30 23:58:02 jason Exp $ */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ */
+
+struct uperf_psycho_attach_args {
+ char *upaa_name;
+ struct perfmon *upaa_regs;
+};
diff --git a/sys/arch/sparc64/dev/uperfvar.h b/sys/arch/sparc64/dev/uperfvar.h
new file mode 100644
index 00000000000..1ead587a5dc
--- /dev/null
+++ b/sys/arch/sparc64/dev/uperfvar.h
@@ -0,0 +1,120 @@
+/* $OpenBSD: uperfvar.h,v 1.1 2002/01/30 23:58:02 jason Exp $ */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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.
+ */
+
+#ifdef _KERNEL
+
+struct uperf_softc {
+ struct device sc_dv;
+ void *usc_cookie; /* cookie to pass upwards */
+ int (*usc_getcntsrc)(void *, int, u_int *, u_int *);
+ int (*usc_setcntsrc)(void *, int, u_int, u_int);
+ int (*usc_clrcnt)(void *, int);
+ int (*usc_getcnt)(void *, int, u_int32_t *, u_int32_t *);
+ struct uperf_src *usc_srcs;
+};
+
+/* Table should be terminated with us_src = -1 */
+struct uperf_src {
+ int us_src; /* source number (user) */
+ int us_flags; /* counters this source is valid for */
+ u_int32_t us_val; /* value to put in register */
+};
+
+#endif
+
+#define UPERF_CNT0 1
+#define UPERF_CNT1 2
+
+#define UPERFSRC_SYSCK 1 /* system clock count */
+#define UPERFSRC_PRALL 2 /* # of p-requests, all srcs */
+#define UPERFSRC_PRP0 3 /* # of p-requests, processor 0 */
+#define UPERFSRC_PRU2S 4 /* # of p-requests, U2S */
+#define UPERFSRC_UPA128 5 /* # cycles UPA 128bit bus busy */
+#define UPERFSRC_UPA64 6 /* # cycles UPA 64bit bus busy */
+#define UPERFSRC_PIOS 7 /* # cycles stalled during PIO */
+#define UPERFSRC_MEMRI 8 /* # memory requests issued */
+#define UPERFSRC_MCBUSY 9 /* # cycles mem ctrlr busy */
+#define UPERFSRC_PXSH 10 /* # cyc stalled for pending xact scoreboard hit */
+#define UPERFSRC_P0CWMR 11 /* # coherent wr miss req, Proc0 */
+#define UPERFSRC_P1CWMR 12 /* # coherent wr miss req, Proc1 */
+#define UPERFSRC_CIT 13 /* # coherent intervention xacts */
+#define UPERFSRC_U2SDAT 14 /* # data xacts from U2S */
+#define UPERFSRC_CRXI 15 /* # coherent read xacts issued */
+#define UPERFSRC_RDP0 16 /* read requests from Proc0 */
+#define UPERFSRC_P0CRMR 17 /* # coherent rd miss req, Proc0 */
+#define UPERFSRC_P0PIO 18 /* PIO accesses from Proc 0 */
+#define UPERFSRC_MEMRC 19 /* # memory requests completed */
+#define UPERFSRC_P1RR 20 /* Proc 1 read requests */
+#define UPERFSRC_CRMP1 21 /* Proc 1 coherent read misses */
+#define UPERFSRC_PIOP1 22 /* Proc 1 PIO accesses */
+#define UPERFSRC_CWXI 23 /* coherent write xacts issued */
+#define UPERFSRC_RP0 24 /* read requests from Proc 0 */
+#define UPERFSRC_SDVRA 25 /* streaming dvma rds, bus A */
+#define UPERFSRC_SDVWA 26 /* streaming dvma wrs, bus A */
+#define UPERFSRC_CDVRA 27 /* consistent dvma rds, bus A */
+#define UPERFSRC_CDVWA 28 /* consistent dvma wrs, bus A */
+#define UPERFSRC_SBMA 29 /* streaming buffer misses, A */
+#define UPERFSRC_DVA 30 /* cycles A granted to dvma */
+#define UPERFSRC_DVWA 31 /* words xfered on bus A */
+#define UPERFSRC_PIOA 32 /* pio cycles on bus A */
+#define UPERFSRC_SDVRB 33 /* streaming dvma rds, bus A */
+#define UPERFSRC_SDVWB 34 /* streaming dvma wrs, bus A */
+#define UPERFSRC_CDVRB 35 /* consistent dvma rds, bus A */
+#define UPERFSRC_CDVWB 36 /* consistent dvma wrs, bus A */
+#define UPERFSRC_SBMB 37 /* streaming buffer misses, A */
+#define UPERFSRC_DVB 38 /* cycles A granted to dvma */
+#define UPERFSRC_DVWB 39 /* words xfered on bus A */
+#define UPERFSRC_PIOB 40 /* pio cycles on bus A */
+#define UPERFSRC_TLBMISS 41 /* tlb misses */
+#define UPERFSRC_NINTRS 42 /* number of interrupts */
+#define UPERFSRC_INACK 43 /* interrupt nacks on UPA */
+#define UPERFSRC_PIOR 44 /* PIO read xfers */
+#define UPERFSRC_PIOW 45 /* PIO write xfers */
+#define UPERFSRC_MERGE 46 /* merge buffer xacts */
+#define UPERFSRC_TBLA 47 /* dma reties for tblwalk, A */
+#define UPERFSRC_STCA 48 /* dma reties for tblwalk, A */
+#define UPERFSRC_TBLB 49 /* dma reties for tblwalk, B */
+#define UPERFSRC_STCB 50 /* dma reties for tblwalk, B */
+
+struct uperf_io {
+ int cnt_flags;
+ int cnt_src0;
+ int cnt_src1;
+ u_int32_t cnt_val0;
+ u_int32_t cnt_val1;
+};
+
+#define UPIO_GCNTSRC _IOWR('U', 0, struct uperf_io) /* get cntr src */
+#define UPIO_SCNTSRC _IOWR('U', 1, struct uperf_io) /* set cntr src */
+#define UPIO_CLRCNT _IOWR('U', 2, struct uperf_io) /* clear cntrs */
+#define UPIO_GETCNT _IOWR('U', 3, struct uperf_io) /* get cntrs */
diff --git a/sys/arch/sparc64/include/conf.h b/sys/arch/sparc64/include/conf.h
index 1d0fe08ec71..7af2252db93 100644
--- a/sys/arch/sparc64/include/conf.h
+++ b/sys/arch/sparc64/include/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.9 2002/01/13 02:06:45 jason Exp $ */
+/* $OpenBSD: conf.h,v 1.10 2002/01/30 23:58:03 jason Exp $ */
/* $NetBSD: conf.h,v 1.9 2001/03/26 12:33:26 lukem Exp $ */
/*-
@@ -47,6 +47,7 @@ cdev_decl(ksyms);
cdev_decl(openprom);
+
/* open, close, ioctl */
#define cdev_openprom_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
@@ -54,6 +55,15 @@ cdev_decl(openprom);
(dev_type_stop((*))) nullop, 0, (dev_type_select((*))) enodev, \
(dev_type_mmap((*))) enodev }
+cdev_decl(uperf);
+
+/* open, close, ioctl */
+#define cdev_uperf_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) nullop, 0, (dev_type_select((*))) enodev, \
+ (dev_type_mmap((*))) enodev }
+
#define cdev_gen_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) nullop, \
diff --git a/sys/arch/sparc64/sparc64/conf.c b/sys/arch/sparc64/sparc64/conf.c
index 0df0d22b179..f223d9ab0d2 100644
--- a/sys/arch/sparc64/sparc64/conf.c
+++ b/sys/arch/sparc64/sparc64/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.25 2002/01/24 03:38:56 jason Exp $ */
+/* $OpenBSD: conf.c,v 1.26 2002/01/30 23:58:03 jason Exp $ */
/* $NetBSD: conf.c,v 1.17 2001/03/26 12:33:26 lukem Exp $ */
/*
@@ -85,6 +85,7 @@
#endif
#include "magma.h" /* has NMTTY and NMBPP */
#include "spif.h" /* has NSTTY and NSBPP */
+#include "uperf.h"
#ifdef notyet
#include "fdc.h" /* has NFDC and NFD; see files.sparc */
@@ -178,7 +179,7 @@ struct cdevsw cdevsw[] =
cdev_fb_init(NFB,fb), /* 22: /dev/fb indirect driver */
cdev_disk_init(NCCD,ccd), /* 23: concatenated disk driver */
cdev_fd_init(1,filedesc), /* 24: file descriptor pseudo-device */
- cdev_notdef(), /* 25 */
+ cdev_uperf_init(NUPERF,uperf), /* 25: performance counters */
cdev_disk_init(NWD,wd), /* 26: IDE disk */
cdev_notdef(), /* 27 */
cdev_notdef(), /* 28: Systech VPC-2200 versatec/centronics */