summaryrefslogtreecommitdiffstats
path: root/sys/arm/mv
diff options
context:
space:
mode:
authorzbb <zbb@FreeBSD.org>2017-06-13 18:55:21 +0000
committerLuiz Souza <luiz@netgate.com>2017-09-06 11:43:11 -0500
commit5f8c047d41e09a01400a008217cab969a23f8537 (patch)
tree98732aaa3388902479adf67f2c6dbc5943b3dd49 /sys/arm/mv
parent3de7f8c40f770b6401eff1375ceaf273ca452eb6 (diff)
downloadFreeBSD-src-5f8c047d41e09a01400a008217cab969a23f8537.zip
FreeBSD-src-5f8c047d41e09a01400a008217cab969a23f8537.tar.gz
Enable HWPMC overflow IRQ on both CPUs in MPIC
This commit enables usage of HWPMC interrupts for the Marvell SoCs, which use MPIC (Armada38x and ArmadaXP). Those interrupts require extra unmasking, comparing to others. Also, in order to process counters per-CPU, they are masked/unmasked using separate registers' sets for each core. Submitted by: Michal Mazur <mkm@semihalf.com> Marcin Wojtas <mw@semihalf.com> Obtained from: Semihalf Sponsored by: Stormshield, Netgate Differential revision: https://reviews.freebsd.org/D10913 (cherry picked from commit 9d6e7340c6b8293f3655371bbab9b1e4dc2fdb4f)
Diffstat (limited to 'sys/arm/mv')
-rw-r--r--sys/arm/mv/mpic.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 49e4bd4..c16bf83 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/rman.h>
#include <sys/proc.h>
+#include <sys/smp.h>
#include <machine/bus.h>
#include <machine/intr.h>
@@ -70,6 +71,7 @@ __FBSDID("$FreeBSD$");
#define debugf(fmt, args...)
#endif
+#define MPIC_INT_LOCAL 3
#define MPIC_INT_ERR 4
#define MPIC_INT_MSI 96
@@ -93,7 +95,9 @@ __FBSDID("$FreeBSD$");
#define MPIC_IIACK 0x44
#define MPIC_ISM 0x48
#define MPIC_ICM 0x4c
-#define MPIC_ERR_MASK 0xe50
+#define MPIC_ERR_MASK 0x50
+#define MPIC_LOCAL_MASK 0x54
+#define MPIC_CPU(n) (n) * 0x100
#define MPIC_PPI 32
@@ -223,6 +227,7 @@ mv_mpic_attach(device_t dev)
struct mv_mpic_softc *sc;
int error;
uint32_t val;
+ int cpu;
sc = (struct mv_mpic_softc *)device_get_softc(dev);
@@ -283,6 +288,12 @@ mv_mpic_attach(device_t dev)
mpic_unmask_msi();
+ /* Unmask CPU performance counters overflow irq */
+ for (cpu = 0; cpu < mp_ncpus; cpu++)
+ MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CPU(cpu) + MPIC_LOCAL_MASK,
+ (1 << cpu) | MPIC_CPU_READ(mv_mpic_sc,
+ MPIC_CPU(cpu) + MPIC_LOCAL_MASK));
+
return (0);
}
@@ -488,6 +499,16 @@ static void
mpic_unmask_irq(uintptr_t nb)
{
+#ifdef SMP
+ int cpu;
+
+ if (nb == MPIC_INT_LOCAL) {
+ for (cpu = 0; cpu < mp_ncpus; cpu++)
+ MPIC_CPU_WRITE(mv_mpic_sc,
+ MPIC_CPU(cpu) + MPIC_ICM, nb);
+ return;
+ }
+#endif
if (mpic_irq_is_percpu(nb))
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, nb);
else if (nb < ERR_IRQ)
@@ -503,6 +524,16 @@ static void
mpic_mask_irq(uintptr_t nb)
{
+#ifdef SMP
+ int cpu;
+
+ if (nb == MPIC_INT_LOCAL) {
+ for (cpu = 0; cpu < mp_ncpus; cpu++)
+ MPIC_CPU_WRITE(mv_mpic_sc,
+ MPIC_CPU(cpu) + MPIC_ISM, nb);
+ return;
+ }
+#endif
if (mpic_irq_is_percpu(nb))
MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ISM, nb);
else if (nb < ERR_IRQ)
OpenPOWER on IntegriCloud