Index: sparc/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v retrieving revision 1.225 diff -p -r1.225 cpu.c *** sparc/cpu.c 22 Jan 2011 12:13:25 -0000 1.225 --- sparc/cpu.c 23 Jan 2011 00:59:21 -0000 *************** xcall(xcall_func_t func, xcall_trap_t tr *** 583,588 **** --- 583,589 ---- volatile struct xpmsg_func *p; int fasttrap; int is_noop = func == (xcall_func_t)sparc_noop; + u_int failed_cpuset = 0; mybit = (1 << cpuinfo.ci_cpuid); callself = func && (cpuset & mybit) != 0; *************** xcall(xcall_func_t func, xcall_trap_t tr *** 645,650 **** --- 646,652 ---- if (cpi->msg.complete == 0) { if (i < 0) { printf_nolog(" cpu%d", cpi->ci_cpuid); + failed_cpuset |= (1 << n); } else { done = 0; break; *************** xcall(xcall_func_t func, xcall_trap_t tr *** 656,661 **** --- 658,671 ---- printf_nolog("\n"); mutex_spin_exit(&xpmsg_mutex); + + /* + * Ping the failed xcall(), see if they can tell us what they + * were doing. + */ + for (CPU_INFO_FOREACH(n, cpi)) + if (failed_cpuset & (1 << n)) + mp_ping_cpu(cpi); } /* *************** mp_resume_cpus_ddb(void) *** 782,787 **** --- 792,809 ---- } } #endif /* DDB */ + + /* + * ping the remote CPU with a highest priority interrupt, used + * when we had an IPI timeout. + */ + void + mp_ping_cpu(struct cpu_info *cpi) + { + + cpi->msg_lev15.tag = XPMSG15_PING; + raise_ipi(cpi,15); /* high priority intr */ + } #endif /* MULTIPROCESSOR */ /* Index: sparc/cpuvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpuvar.h,v retrieving revision 1.84 diff -p -r1.84 cpuvar.h *** sparc/cpuvar.h 13 Jan 2011 05:20:27 -0000 1.84 --- sparc/cpuvar.h 23 Jan 2011 00:59:21 -0000 *************** struct xpmsg { *** 96,101 **** --- 96,102 ---- #define XPMSG15_PAUSECPU 1 #define XPMSG_FUNC 4 #define XPMSG_FTRP 5 + #define XPMSG15_PING 6 volatile union { /* *************** extern int bootmid; /* Module ID of bo *** 488,493 **** --- 489,495 ---- extern struct cpu_info *cpus[]; #ifdef MULTIPROCESSOR extern u_int cpu_ready_mask; /* the set of CPUs marked as READY */ + void mp_ping_cpu(struct cpu_info *cpi); /* are you alive? */ #endif #define cpuinfo (*(struct cpu_info *)CPUINFO_VA) Index: sparc/intr.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/intr.c,v retrieving revision 1.109 diff -p -r1.109 intr.c *** sparc/intr.c 22 Jan 2011 10:37:22 -0000 1.109 --- sparc/intr.c 23 Jan 2011 00:59:21 -0000 *************** nmi_soft(struct trapframe *tf) *** 369,374 **** --- 369,384 ---- while (cpuinfo.flags & CPUFLG_PAUSED) /* spin */; #endif /* DDB */ + break; + + case XPMSG15_PING: + /* XXX printf_nolog() at IPL 15? */ + printf_nolog("cpu%d: ping while pc/npc %#x/%#x psr %#x" + " %%o7 %#x\n", cpu_number(), + tf->tf_pc, tf->tf_npc, tf->tf_psr, + tf->tf_out[7]); + break; + } cpuinfo.msg_lev15.tag = 0; #endif /* MULTIPROCESSOR */ Index: sparc/locore.s =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/locore.s,v retrieving revision 1.259 diff -p -r1.259 locore.s *** sparc/locore.s 13 Jan 2011 05:20:27 -0000 1.259 --- sparc/locore.s 23 Jan 2011 00:59:22 -0000 *************** _ENTRY(_C_LABEL(nmi_sun4m)) *** 3092,3103 **** 1: #if defined(MULTIPROCESSOR) && defined(DDB) /* ! * Setup a trapframe for nmi_soft; this might be an IPI telling ! * us to pause, so lets save some state for DDB to get at. */ - std %l0, [%sp + CCFSZ] ! tf.tf_psr = psr; tf.tf_pc = ret_pc; rd %y, %l3 std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc = return_npc; tf.tf_y = %y; st %g1, [%sp + CCFSZ + 20] std %g2, [%sp + CCFSZ + 24] std %g4, [%sp + CCFSZ + 32] --- 3092,3105 ---- 1: #if defined(MULTIPROCESSOR) && defined(DDB) /* ! * Setup a trapframe for nmi_soft; this might be an IPI telling us ! * to pause or ping, so lets save some state for them to get at. */ rd %y, %l3 + std %l0, [%sp + CCFSZ] ! tf.tf_psr = psr; tf.tf_pc = ret_pc; + rd %wim, %l4 std %l2, [%sp + CCFSZ + 8] ! tf.tf_npc = return_npc; tf.tf_y = %y; + st %l4, [%sp + CCFSZ + 16] ! tf.tf_global[0] = %wim st %g1, [%sp + CCFSZ + 20] std %g2, [%sp + CCFSZ + 24] std %g4, [%sp + CCFSZ + 32]