diff options
Diffstat (limited to 'sys/mips/mips/mp_machdep.c')
-rw-r--r-- | sys/mips/mips/mp_machdep.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c index d8520cc..f65db9b 100644 --- a/sys/mips/mips/mp_machdep.c +++ b/sys/mips/mips/mp_machdep.c @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include <machine/intr_machdep.h> #include <machine/cache.h> +struct pcb stoppcbs[MAXCPU]; + static void *dpcpu; static struct mtx ap_boot_mtx; @@ -88,10 +90,14 @@ ipi_selected(cpumask_t cpus, int ipi) static int mips_ipi_handler(void *arg) { + int cpu; cpumask_t cpumask; u_int ipi, ipi_bitmap; int bit; + cpu = PCPU_GET(cpuid); + cpumask = PCPU_GET(cpumask); + platform_ipi_clear(); /* quiesce the pending ipi interrupt */ ipi_bitmap = atomic_readandclear_int(PCPU_PTR(pending_ipis)); @@ -120,10 +126,17 @@ mips_ipi_handler(void *arg) * necessary to add it in the switch. */ CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD"); - cpumask = PCPU_GET(cpumask); + + savectx(&stoppcbs[cpu]); + pmap_save_tlb(); + + /* Indicate we are stopped */ atomic_set_int(&stopped_cpus, cpumask); + + /* Wait for restart */ while ((started_cpus & cpumask) == 0) cpu_spinwait(); + atomic_clear_int(&started_cpus, cpumask); atomic_clear_int(&stopped_cpus, cpumask); CTR0(KTR_SMP, "IPI_STOP (restart)"); |