* Handle an IPI sent to this processor. */
| 113 | * Handle an IPI sent to this processor. |
| 114 | */ |
| 115 | static int |
| 116 | mips_ipi_handler(void *arg) |
| 117 | { |
| 118 | u_int cpu, ipi, ipi_bitmap; |
| 119 | int bit; |
| 120 | |
| 121 | cpu = PCPU_GET(cpuid); |
| 122 | |
| 123 | platform_ipi_clear(); /* quiesce the pending ipi interrupt */ |
| 124 | |
| 125 | ipi_bitmap = atomic_readandclear_int(PCPU_PTR(pending_ipis)); |
| 126 | if (ipi_bitmap == 0) |
| 127 | return (FILTER_STRAY); |
| 128 | |
| 129 | CTR1(KTR_SMP, "smp_handle_ipi(), ipi_bitmap=%x", ipi_bitmap); |
| 130 | |
| 131 | while ((bit = ffs(ipi_bitmap))) { |
| 132 | bit = bit - 1; |
| 133 | ipi = 1 << bit; |
| 134 | ipi_bitmap &= ~ipi; |
| 135 | switch (ipi) { |
| 136 | case IPI_RENDEZVOUS: |
| 137 | CTR0(KTR_SMP, "IPI_RENDEZVOUS"); |
| 138 | smp_rendezvous_action(); |
| 139 | break; |
| 140 | |
| 141 | case IPI_AST: |
| 142 | CTR0(KTR_SMP, "IPI_AST"); |
| 143 | break; |
| 144 | |
| 145 | case IPI_STOP: |
| 146 | /* |
| 147 | * IPI_STOP_HARD is mapped to IPI_STOP so it is not |
| 148 | * necessary to add it in the switch. |
| 149 | */ |
| 150 | CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD"); |
| 151 | |
| 152 | savectx(&stoppcbs[cpu]); |
| 153 | tlb_save(); |
| 154 | |
| 155 | /* Indicate we are stopped */ |
| 156 | CPU_SET_ATOMIC(cpu, &stopped_cpus); |
| 157 | |
| 158 | /* Wait for restart */ |
| 159 | while (!CPU_ISSET(cpu, &started_cpus)) |
| 160 | cpu_spinwait(); |
| 161 | |
| 162 | CPU_CLR_ATOMIC(cpu, &started_cpus); |
| 163 | CPU_CLR_ATOMIC(cpu, &stopped_cpus); |
| 164 | CTR0(KTR_SMP, "IPI_STOP (restart)"); |
| 165 | break; |
| 166 | case IPI_PREEMPT: |
| 167 | CTR1(KTR_SMP, "%s: IPI_PREEMPT", __func__); |
| 168 | sched_preempt(curthread); |
| 169 | break; |
| 170 | case IPI_HARDCLOCK: |
| 171 | CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__); |
| 172 | hardclockintr(); |
nothing calls this directly
no test coverage detected