static void openpic_send_ipi(cpuid_t target, uint32_t mesg) { struct cpu_info * const ci = curcpu(); uint32_t cpumask = 0; switch (target) { case IPI_DST_ALL: case IPI_DST_NOTME: for (u_int i = 0; i < ncpu; i++) { struct cpu_info * const dst_ci = cpu_lookup(i); if (target == IPI_DST_ALL || dst_ci != ci) { cpumask |= 1 << cpu_index(dst_ci); atomic_or_32(&dst_ci->ci_pending_ipis, mesg); } } break; default: { struct cpu_info * const dst_ci = cpu_lookup(target); cpumask = 1 << cpu_index(dst_ci); atomic_or_32(&dst_ci->ci_pending_ipis, mesg); break; } } openpic_write(OPENPIC_IPI(cpu_index(ci), 1), cpumask); }
void cpu_multicast_ipi(const kcpuset_t *kcp, int tag) { struct cpu_info * const ci = curcpu(); kcpuset_t *kcp2 = ci->ci_multicastcpus; if (kcpuset_match(cpus_running, ci->ci_data.cpu_kcpuset)) return; kcpuset_copy(kcp2, kcp); kcpuset_remove(kcp2, ci->ci_data.cpu_kcpuset); for (cpuid_t cii; (cii = kcpuset_ffs(kcp2)) != 0; ) { kcpuset_clear(kcp2, --cii); (void)cpu_send_ipi(cpu_lookup(cii), tag); } }
void db_switch_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) { if (addr >= maxcpus) { db_printf("cpu %"DDB_EXPR_FMT"d out of range", addr); return; } struct cpu_info *new_ci = cpu_lookup(addr); if (new_ci == NULL) { db_printf("cpu %"DDB_EXPR_FMT"d does not exist", addr); return; } if (DDB_REGS->tf_spsr & PSR_T_bit) { DDB_REGS->tf_pc -= 2; /* XXX */ } else { DDB_REGS->tf_pc -= 4; } db_newcpu = new_ci; db_continue_cmd(0, false, 0, ""); }