Index: timer.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timer.c,v retrieving revision 1.22 diff -p -r1.22 timer.c *** timer.c 7 Jun 2006 22:38:50 -0000 1.22 --- timer.c 4 Mar 2011 01:13:47 -0000 *************** void *** 153,158 **** --- 153,159 ---- timerattach(volatile int *cntreg, volatile int *limreg) { u_int prec = 0, t0; + void (*sched_intr_fn)(void *); /* * Calibrate delay() by tweaking the magic constant *************** timerattach(volatile int *cntreg, volati *** 197,202 **** --- 198,204 ---- #if defined(SUN4) || defined(SUN4C) if (CPU_ISSUN4 || CPU_ISSUN4C) { timer_init = timer_init_4; + sched_intr_fn = schedintr; level10.ih_fun = clockintr_4; level14.ih_fun = statintr_4; cntr.limit = tmr_ustolim(tick); *************** timerattach(volatile int *cntreg, volati *** 205,210 **** --- 207,218 ---- #if defined(SUN4M) if (CPU_ISSUN4M) { timer_init = timer_init_4m; + #if defined(MULTIPROCESSOR) + if (sparc_ncpus > 1) + sched_intr_fn = schedintr_4m; + else + #endif + sched_intr_fn = schedintr; level10.ih_fun = clockintr_4m; level14.ih_fun = statintr_4m; cntr.limit = tmr_ustolim4m(tick); *************** timerattach(volatile int *cntreg, volati *** 215,221 **** intr_establish(14, 0, &level14, NULL); /* Establish a soft interrupt at a lower level for schedclock */ ! sched_cookie = softintr_establish(IPL_SCHED, schedintr, NULL); if (sched_cookie == NULL) panic("timerattach: cannot establish schedintr"); --- 223,229 ---- intr_establish(14, 0, &level14, NULL); /* Establish a soft interrupt at a lower level for schedclock */ ! sched_cookie = softintr_establish(IPL_SCHED, sched_intr_fn, NULL); if (sched_cookie == NULL) panic("timerattach: cannot establish schedintr"); Index: timer_sun4m.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timer_sun4m.c,v retrieving revision 1.15 diff -p -r1.15 timer_sun4m.c *** timer_sun4m.c 7 Jun 2006 22:38:50 -0000 1.15 --- timer_sun4m.c 4 Mar 2011 01:13:47 -0000 *************** timer_init_4m(void) *** 97,102 **** --- 97,128 ---- icr_si_bic(SINTR_T); } + void + schedintr_4m(void *v) + { + struct lwp *l = curlwp; + + #ifdef MULTIPROCESSOR + /* + * We call hardclock() here so that we make sure it is called on + * all CPUs. This function ends up being called on sun4m systems + * every tick. + */ + if (!cpuinfo.master) + hardclock(v); + + /* XXX - should consult a cpuinfo.schedtickpending */ + if (l == NULL) + return; + /* + * The factor 8 is only valid for stathz==100. + * See also clock.c + */ + if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0 && schedhz != 0) + #endif + schedclock(l); + } + /* * Level 10 (clock) interrupts from system counter. */ *************** int *** 104,109 **** --- 130,148 ---- clockintr_4m(void *cap) { + /* + * XXX this needs to be fixed in a more general way + * problem is that the kernel enables interrupts and THEN + * sets up clocks. In between there's an opportunity to catch + * a timer interrupt - if we call hardclock() at that point we'll + * panic + * so for now just bail when cold + * + * For MP, we defer calling hardclock() to the schedintr so + * that we call it on all cpus. + */ + if (cold) + return 0; /* read the limit register to clear the interrupt */ *((volatile int *)&timerreg4m->t_limit); tickle_tc(); *************** statintr_4m(void *cap) *** 141,147 **** --- 180,188 ---- * The factor 8 is only valid for stathz==100. * See also clock.c */ + #if !defined(MULTIPROCESSOR) if (curlwp && (++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0) { + #endif if (CLKF_LOPRI(frame, IPL_SCHED)) { /* No need to schedule a soft interrupt */ spllowerschedclock(); *************** statintr_4m(void *cap) *** 153,159 **** --- 194,202 ---- */ raise_ipi(&cpuinfo, IPL_SCHED); /* sched_cookie->pil */ } + #if !defined(MULTIPROCESSOR) } + #endif return (1); } Index: timervar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timervar.h,v retrieving revision 1.8 diff -p -r1.8 timervar.h *** timervar.h 7 Jun 2006 22:38:50 -0000 1.8 --- timervar.h 4 Mar 2011 01:13:47 -0000 *************** void timerattach_mainbus_4c(struct devic *** 50,55 **** --- 50,56 ---- #endif /* SUN4 || SUN4C */ #if defined(SUN4M) + void schedintr_4m(void *); int clockintr_4m(void *); int statintr_4m(void *); void timer_init_4m(void);