summaryrefslogtreecommitdiffstats
path: root/sys/mips/mips/mp_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/mips/mips/mp_machdep.c')
-rw-r--r--sys/mips/mips/mp_machdep.c15
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)");
OpenPOWER on IntegriCloud