Index: octeon_pmc.c =================================================================== --- octeon_pmc.c (revision 233380) +++ octeon_pmc.c (working copy) @@ -37,9 +37,11 @@ #include #include #include -#include #include #include +#include +#include +#include #include #include @@ -60,6 +62,19 @@ #define OCTEON_PMC_IRQ 4 static void +octeon_pmc_remap_irq(void* arg) +{ + uint64_t cvmctl; + int irq = (int)(vm_offset_t)arg; + + printf("REMAPPING %d\n", curcpu); + cvmctl = mips_rd_cvmctl(); + cvmctl &= ~(7 << 7); + cvmctl |= (irq + 2) << 7; + mips_wr_cvmctl(cvmctl); +} + +static void octeon_pmc_identify(driver_t *drv, device_t parent) { if (octeon_has_feature(OCTEON_FEATURE_USB)) @@ -82,7 +97,9 @@ struct octeon_pmc_softc *sc; int error; int rid; - uint64_t cvmctl; + int i; + cpuset_t map; + struct pcpu *pc; sc = device_get_softc(dev); @@ -103,14 +120,31 @@ return (error); } + sched_pin(); /* * 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); + printf("CURCPU == %d\n", curcpu); + octeon_pmc_remap_irq((void*)OCTEON_PMC_IRQ); + + CPU_FOREACH(i) { + if (i == curcpu) + continue; + + printf("CPU_FOREACH (%d, %d)\n", curcpu, i); + pc = pcpu_find(i); + CPU_SETOF(PCPU_GET(cpuid), &map); + CPU_SET(pc->pc_cpuid, &map); + + smp_rendezvous_cpus(map, NULL, + octeon_pmc_remap_irq, + smp_no_rendevous_barrier, (void *)OCTEON_PMC_IRQ); + + } + + sched_unpin(); + return (0); }