summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-03-23 00:11:54 +0000
committergonzo <gonzo@FreeBSD.org>2012-03-23 00:11:54 +0000
commit0450849e9cfb65a556aecc37fa3485430f246239 (patch)
treedd7bb59bfa67d0d3f488b011564a7d1108246a82 /sys/mips
parent42ce1eaaa2ad8c57c9f0cc3628042030b80344cd (diff)
downloadFreeBSD-src-0450849e9cfb65a556aecc37fa3485430f246239.zip
FreeBSD-src-0450849e9cfb65a556aecc37fa3485430f246239.tar.gz
Add pseudo-device for handling PMC interrupts and link everything
PMC-related to build
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/cavium/files.octeon14
-rw-r--r--sys/mips/cavium/octeon_pmc.c141
2 files changed, 145 insertions, 0 deletions
diff --git a/sys/mips/cavium/files.octeon1 b/sys/mips/cavium/files.octeon1
index a6c3b9b..fbcfbbf 100644
--- a/sys/mips/cavium/files.octeon1
+++ b/sys/mips/cavium/files.octeon1
@@ -8,6 +8,7 @@ mips/cavium/octeon_ds1337.c standard
mips/cavium/octeon_ebt3000_cf.c optional cf
mips/cavium/octeon_machdep.c standard
mips/cavium/octeon_mp.c optional smp
+mips/cavium/octeon_pmc.c optional hwpmc
mips/cavium/octeon_rtc.c standard
mips/cavium/uart_bus_octeonusart.c optional uart
mips/cavium/uart_cpu_octeonusart.c optional uart
@@ -88,3 +89,6 @@ contrib/octeon-sdk/cvmx-thunder.c standard
contrib/octeon-sdk/cvmx-twsi.c standard
contrib/octeon-sdk/cvmx-warn.c standard
contrib/octeon-sdk/octeon-model.c standard
+
+# HWPMC
+dev/hwpmc/hwpmc_octeon.c optional hwpmc
diff --git a/sys/mips/cavium/octeon_pmc.c b/sys/mips/cavium/octeon_pmc.c
new file mode 100644
index 0000000..8a7b573
--- /dev/null
+++ b/sys/mips/cavium/octeon_pmc.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+#include <sys/smp.h>
+#include <sys/pmc.h>
+#include <sys/pmckern.h>
+
+#include <machine/bus.h>
+#include <machine/intr_machdep.h>
+
+#include <contrib/octeon-sdk/cvmx.h>
+#include <mips/cavium/octeon_irq.h>
+
+struct octeon_pmc_softc {
+ struct rman irq_rman;
+ struct resource *octeon_pmc_irq;
+};
+
+static void octeon_pmc_identify(driver_t *, device_t);
+static int octeon_pmc_probe(device_t);
+static int octeon_pmc_attach(device_t);
+static int octeon_pmc_intr(void *);
+
+#define OCTEON_PMC_IRQ 4
+
+static void
+octeon_pmc_identify(driver_t *drv, device_t parent)
+{
+ if (octeon_has_feature(OCTEON_FEATURE_USB))
+ BUS_ADD_CHILD(parent, 0, "pmc", 0);
+}
+
+static int
+octeon_pmc_probe(device_t dev)
+{
+ if (device_get_unit(dev) != 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Cavium Octeon Performance Counters");
+ return (0);
+}
+
+static int
+octeon_pmc_attach(device_t dev)
+{
+ struct octeon_pmc_softc *sc;
+ int error;
+ int rid;
+ uint64_t cvmctl;
+
+ sc = device_get_softc(dev);
+
+ rid = 0;
+ sc->octeon_pmc_irq = bus_alloc_resource(dev,
+ SYS_RES_IRQ, &rid, OCTEON_PMC_IRQ,
+ OCTEON_PMC_IRQ, 1, RF_ACTIVE);
+
+ if (sc->octeon_pmc_irq == NULL) {
+ device_printf(dev, "could not allocate irq%d\n", OCTEON_PMC_IRQ);
+ return (ENXIO);
+ }
+
+ error = bus_setup_intr(dev, sc->octeon_pmc_irq,
+ INTR_TYPE_MISC, octeon_pmc_intr, NULL, sc, NULL);
+ if (error != 0) {
+ device_printf(dev, "bus_setup_intr failed: %d\n", error);
+ return (error);
+ }
+
+ /*
+ * Move the Performance Counter interrupt to OCTEON_PMC_IRQ
+ */
+ cvmctl = mips_rd_cvmctl();
+ cvmctl &= ~(7 << 7);
+ cvmctl |= (OCTEON_PMC_IRQ + 2) << 7;
+ mips_wr_cvmctl(cvmctl);
+
+ return (0);
+}
+
+static int
+octeon_pmc_intr(void *arg)
+{
+ struct trapframe *tf = PCPU_GET(curthread)->td_intr_frame;
+
+ if (pmc_intr)
+ (*pmc_intr)(PCPU_GET(cpuid), tf);
+
+ return (FILTER_HANDLED);
+}
+
+static device_method_t octeon_pmc_methods[] = {
+ DEVMETHOD(device_identify, octeon_pmc_identify),
+ DEVMETHOD(device_probe, octeon_pmc_probe),
+ DEVMETHOD(device_attach, octeon_pmc_attach),
+ { 0, 0 }
+};
+
+static driver_t octeon_pmc_driver = {
+ "pmc",
+ octeon_pmc_methods,
+ sizeof(struct octeon_pmc_softc),
+};
+static devclass_t octeon_pmc_devclass;
+DRIVER_MODULE(octeon_pmc, nexus, octeon_pmc_driver, octeon_pmc_devclass, 0, 0);
OpenPOWER on IntegriCloud