svn commit: r212453 - in head/sys: conf powerpc/aim powerpc/booke powerpc/include powerpc/powerpc

Alexander Motin mav at FreeBSD.org
Sat Sep 11 04:45:52 UTC 2010


Author: mav
Date: Sat Sep 11 04:45:51 2010
New Revision: 212453
URL: http://svn.freebsd.org/changeset/base/212453

Log:
  Update PowerPC event timer code to use new event timers infrastructure.
  
  Reviewed by:	nwitehorn
  Tested by:	andreast
  H/W donated by:	Gheorghe Ardelean

Modified:
  head/sys/conf/files.powerpc
  head/sys/powerpc/aim/clock.c
  head/sys/powerpc/aim/interrupt.c
  head/sys/powerpc/aim/machdep.c
  head/sys/powerpc/booke/clock.c
  head/sys/powerpc/booke/interrupt.c
  head/sys/powerpc/booke/platform_bare.c
  head/sys/powerpc/include/intr_machdep.h
  head/sys/powerpc/include/md_var.h
  head/sys/powerpc/include/smp.h
  head/sys/powerpc/powerpc/intr_machdep.c
  head/sys/powerpc/powerpc/mp_machdep.c

Modified: head/sys/conf/files.powerpc
==============================================================================
--- head/sys/conf/files.powerpc	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/conf/files.powerpc	Sat Sep 11 04:45:51 2010	(r212453)
@@ -52,6 +52,7 @@ dev/syscons/scvtb.c		optional	sc
 dev/tsec/if_tsec.c		optional	tsec
 dev/tsec/if_tsec_fdt.c		optional	tsec fdt
 dev/uart/uart_cpu_powerpc.c	optional	uart aim
+kern/kern_clocksource.c		standard
 kern/syscalls.c			optional	ktr
 libkern/ashldi3.c		optional	powerpc
 libkern/ashrdi3.c		optional	powerpc

Modified: head/sys/powerpc/aim/clock.c
==============================================================================
--- head/sys/powerpc/aim/clock.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/aim/clock.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -65,107 +65,195 @@ __FBSDID("$FreeBSD$");
 #include <sys/interrupt.h>
 #include <sys/pcpu.h>
 #include <sys/sysctl.h>
+#include <sys/timeet.h>
 #include <sys/timetc.h>
 
 #include <dev/ofw/openfirm.h>
 
 #include <machine/clock.h>
 #include <machine/cpu.h>
+#include <machine/intr_machdep.h>
 #include <machine/md_var.h>
 #include <machine/smp.h>
 
 /*
  * Initially we assume a processor with a bus frequency of 12.5 MHz.
  */
-u_long			ns_per_tick = 80;
+static int		initialized = 0;
+static u_long		ns_per_tick = 80;
 static u_long		ticks_per_sec = 12500000;
-static long		ticks_per_intr;
+static u_long		*decr_counts[MAXCPU];
 
+static int		decr_et_start(struct eventtimer *et,
+    struct bintime *first, struct bintime *period);
+static int		decr_et_stop(struct eventtimer *et);
 static timecounter_get_t	decr_get_timecount;
 
-static struct timecounter	decr_timecounter = {
+struct decr_state {
+	int	mode;	/* 0 - off, 1 - periodic, 2 - one-shot. */
+	int32_t	div;	/* Periodic divisor. */
+};
+static DPCPU_DEFINE(struct decr_state, decr_state);
+
+static struct eventtimer	decr_et;
+static struct timecounter	decr_tc = {
 	decr_get_timecount,	/* get_timecount */
 	0,			/* no poll_pps */
 	~0u,			/* counter_mask */
 	0,			/* frequency */
-	"decrementer"		/* name */
+	"timebase"		/* name */
 };
 
+/*
+ * Decrementor interrupt handler.
+ */
 void
 decr_intr(struct trapframe *frame)
 {
-	int32_t		tick, nticks;
+	struct decr_state *s = DPCPU_PTR(decr_state);
+	int		nticks = 0;
+	int32_t		val;
 
-	/*
-	 * Check whether we are initialized.
-	 */
-	if (!ticks_per_intr)
+	if (!initialized)
 		return;
 
-	/*
-	 * Based on the actual time delay since the last decrementer reload,
-	 * we arrange for earlier interrupt next time.
-	 */
-	__asm ("mfdec %0" : "=r"(tick));
-	for (nticks = 0; tick < 0; nticks++)
-		tick += ticks_per_intr;
-	mtdec(tick);
+	(*decr_counts[curcpu])++;
+
+	if (s->mode == 1) {
+		/*
+		 * Based on the actual time delay since the last decrementer
+		 * reload, we arrange for earlier interrupt next time.
+		 */
+		__asm ("mfdec %0" : "=r"(val));
+		while (val < 0) {
+			val += s->div;
+			nticks++;
+		}
+		mtdec(val);
+	} else if (s->mode == 2) {
+		nticks = 1;
+		decr_et_stop(NULL);
+	}
 
 	while (nticks-- > 0) {
-		if (PCPU_GET(cpuid) == 0)
-			hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-		else
-			hardclock_cpu(TRAPF_USERMODE(frame));
-
-		statclock(TRAPF_USERMODE(frame));
-		if (profprocs != 0)
-			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+		if (decr_et.et_active)
+			decr_et.et_event_cb(&decr_et, decr_et.et_arg);
 	}
 }
 
+/*
+ * BSP early initialization.
+ */
 void
 decr_init(void)
 {
 	struct cpuref cpu;
-	register_t msr;
+	char buf[32];
 
 	/*
 	 * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall
 	 * back to the first CPU in this case.
 	 */
-
 	if (platform_smp_get_bsp(&cpu) != 0)
 		platform_smp_first_cpu(&cpu);
-
 	ticks_per_sec = platform_timebase_freq(&cpu);
-
-	msr = mfmsr();
-	mtmsr(msr & ~PSL_EE);
-
 	ns_per_tick = 1000000000 / ticks_per_sec;
-	ticks_per_intr = ticks_per_sec / hz;
-	mtdec(ticks_per_intr);
 
 	set_cputicker(mftb, ticks_per_sec, 0);
-
-	mtmsr(msr);
+	snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
+	intrcnt_add(buf, &decr_counts[curcpu]);
+	decr_et_stop(NULL);
+	initialized = 1;
 }
 
 #ifdef SMP
+/*
+ * AP early initialization.
+ */
 void
 decr_ap_init(void)
 {
+	char buf[32];
 
+	snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
+	intrcnt_add(buf, &decr_counts[curcpu]);
+	decr_et_stop(NULL);
 }
 #endif
 
+/*
+ * Final initialization.
+ */
 void
 decr_tc_init(void)
 {
-	decr_timecounter.tc_frequency = ticks_per_sec;
-	tc_init(&decr_timecounter);
+
+	decr_tc.tc_frequency = ticks_per_sec;
+	tc_init(&decr_tc);
+	decr_et.et_name = "decrementer";
+	decr_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
+	    ET_FLAGS_PERCPU;
+	decr_et.et_quality = 1000;
+	decr_et.et_frequency = ticks_per_sec;
+	decr_et.et_min_period.sec = 0;
+	decr_et.et_min_period.frac =
+	    ((0x00000002LLU << 32) / ticks_per_sec) << 32;
+	decr_et.et_max_period.sec = 0x7fffffffLLU / ticks_per_sec;
+	decr_et.et_max_period.frac =
+	    ((0x7fffffffLLU << 32) / ticks_per_sec) << 32;
+	decr_et.et_start = decr_et_start;
+	decr_et.et_stop = decr_et_stop;
+	decr_et.et_priv = NULL;
+	et_register(&decr_et);
+}
+
+/*
+ * Event timer start method.
+ */
+static int
+decr_et_start(struct eventtimer *et,
+    struct bintime *first, struct bintime *period)
+{
+	struct decr_state *s = DPCPU_PTR(decr_state);
+	uint32_t fdiv;
+
+	if (period != NULL) {
+		s->mode = 1;
+		s->div = (decr_et.et_frequency * (period->frac >> 32)) >> 32;
+		if (period->sec != 0)
+			s->div += decr_et.et_frequency * period->sec;
+	} else {
+		s->mode = 2;
+		s->div = 0x7fffffff;
+	}
+	if (first != NULL) {
+		fdiv = (decr_et.et_frequency * (first->frac >> 32)) >> 32;
+		if (first->sec != 0)
+			fdiv += decr_et.et_frequency * first->sec;
+	} else
+		fdiv = s->div;
+
+	mtdec(fdiv);
+	return (0);
+}
+
+/*
+ * Event timer stop method.
+ */
+static int
+decr_et_stop(struct eventtimer *et)
+{
+	struct decr_state *s = DPCPU_PTR(decr_state);
+
+	s->mode = 0;
+	s->div = 0x7fffffff;
+	mtdec(s->div);
+	return (0);
 }
 
+/*
+ * Timecounter get method.
+ */
 static unsigned
 decr_get_timecount(struct timecounter *tc)
 {
@@ -189,17 +277,3 @@ DELAY(int n)
 		tb = mftb();
 }
 
-/*
- * Nothing to do.
- */
-void
-cpu_startprofclock(void)
-{
-
-	/* Do nothing */
-}
-
-void
-cpu_stopprofclock(void)
-{
-}

Modified: head/sys/powerpc/aim/interrupt.c
==============================================================================
--- head/sys/powerpc/aim/interrupt.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/aim/interrupt.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -72,6 +72,7 @@ void
 powerpc_interrupt(struct trapframe *framep)
 {
 	struct thread *td;
+	struct trapframe *oldframe;
 	register_t ee;
 
 	td = curthread;
@@ -88,8 +89,11 @@ powerpc_interrupt(struct trapframe *fram
 	case EXC_DECR:
 		critical_enter();
 		atomic_add_int(&td->td_intr_nesting_level, 1);
+		oldframe = td->td_intr_frame;
+		td->td_intr_frame = framep;
 		decr_intr(framep);
-		atomic_subtract_int(&td->td_intr_nesting_level, 1);	
+		td->td_intr_frame = oldframe;
+		atomic_subtract_int(&td->td_intr_nesting_level, 1);
 		critical_exit();
 		break;
 

Modified: head/sys/powerpc/aim/machdep.c
==============================================================================
--- head/sys/powerpc/aim/machdep.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/aim/machdep.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -609,8 +609,7 @@ cpu_initclocks(void)
 {
 
 	decr_tc_init();
-	stathz = hz;
-	profhz = hz;
+	cpu_initclocks_bsp();
 }
 
 /*

Modified: head/sys/powerpc/booke/clock.c
==============================================================================
--- head/sys/powerpc/booke/clock.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/booke/clock.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -63,12 +63,14 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/bus.h>
+#include <sys/interrupt.h>
 #include <sys/ktr.h>
 #include <sys/pcpu.h>
+#include <sys/timeet.h>
 #include <sys/timetc.h>
-#include <sys/interrupt.h>
 
 #include <machine/clock.h>
+#include <machine/intr_machdep.h>
 #include <machine/platform.h>
 #include <machine/psl.h>
 #include <machine/spr.h>
@@ -78,33 +80,46 @@ __FBSDID("$FreeBSD$");
 /*
  * Initially we assume a processor with a bus frequency of 12.5 MHz.
  */
-u_int tickspending;
-u_long ns_per_tick = 80;
-static u_long ticks_per_sec = 12500000;
-static long ticks_per_intr;
+static int		initialized = 0;
+static u_long		ns_per_tick = 80;
+static u_long		ticks_per_sec = 12500000;
+static u_long		*decr_counts[MAXCPU];
 
 #define	DIFF19041970	2082844800
 
+static int		decr_et_start(struct eventtimer *et,
+    struct bintime *first, struct bintime *period);
+static int		decr_et_stop(struct eventtimer *et);
 static timecounter_get_t decr_get_timecount;
 
+struct decr_state {
+	int	mode;	/* 0 - off, 1 - periodic, 2 - one-shot. */
+	int32_t	div;	/* Periodic divisor. */
+};
+static DPCPU_DEFINE(struct decr_state, decr_state);
+
+static struct eventtimer	decr_et;
 static struct timecounter	decr_timecounter = {
 	decr_get_timecount,	/* get_timecount */
 	0,			/* no poll_pps */
 	~0u,			/* counter_mask */
 	0,			/* frequency */
-	"decrementer"		/* name */
+	"timebase"		/* name */
 };
 
+/*
+ * Decrementor interrupt handler.
+ */
 void
 decr_intr(struct trapframe *frame)
 {
+	struct decr_state *s = DPCPU_PTR(decr_state);
 
-	/*
-	 * Check whether we are initialized.
-	 */
-	if (!ticks_per_intr)
+	if (!initialized)
 		return;
 
+	(*decr_counts[curcpu])++;
+
 	/*
 	 * Interrupt handler must reset DIS to avoid getting another
 	 * interrupt once EE is enabled.
@@ -113,14 +128,11 @@ decr_intr(struct trapframe *frame)
 
 	CTR1(KTR_INTR, "%s: DEC interrupt", __func__);
 
-	if (PCPU_GET(cpuid) == 0)
-		hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-	else
-		hardclock_cpu(TRAPF_USERMODE(frame));
-
-	statclock(TRAPF_USERMODE(frame));
-	if (profprocs != 0)
-		profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	if (s->mode == 2)
+		decr_et_stop(NULL);
+
+	if (decr_et.et_active)
+		decr_et.et_event_cb(&decr_et, decr_et.et_arg);
 }
 
 void
@@ -128,57 +140,129 @@ cpu_initclocks(void)
 {
 
 	decr_tc_init();
-	stathz = hz;
-	profhz = hz;
+	cpu_initclocks_bsp();
 }
 
+/*
+ * BSP early initialization.
+ */
 void
 decr_init(void)
 {
 	struct cpuref cpu;
-	unsigned int msr;
+	char buf[32];
 
 	if (platform_smp_get_bsp(&cpu) != 0)
 		platform_smp_first_cpu(&cpu);
 	ticks_per_sec = platform_timebase_freq(&cpu);
-
-	msr = mfmsr();
-	mtmsr(msr & ~(PSL_EE));
-
 	ns_per_tick = 1000000000 / ticks_per_sec;
-	ticks_per_intr = ticks_per_sec / hz;
-
-	mtdec(ticks_per_intr);
-
-	mtspr(SPR_DECAR, ticks_per_intr);
-	mtspr(SPR_TCR, mfspr(SPR_TCR) | TCR_DIE | TCR_ARE);
 
 	set_cputicker(mftb, ticks_per_sec, 0);
-
-	mtmsr(msr);
+	snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
+	intrcnt_add(buf, &decr_counts[curcpu]);
+	decr_et_stop(NULL);
+	initialized = 1;
 }
 
 #ifdef SMP
+/*
+ * AP early initialization.
+ */
 void
 decr_ap_init(void)
 {
+	char buf[32];
 
-	/* Set auto-reload value and enable DEC interrupts in TCR */
-	mtspr(SPR_DECAR, ticks_per_intr);
-	mtspr(SPR_TCR, mfspr(SPR_TCR) | TCR_DIE | TCR_ARE);
-
-	CTR2(KTR_INTR, "%s: set TCR=%p", __func__, mfspr(SPR_TCR));
+	snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
+	intrcnt_add(buf, &decr_counts[curcpu]);
+	decr_et_stop(NULL);
 }
 #endif
 
+/*
+ * Final initialization.
+ */
 void
 decr_tc_init(void)
 {
 
 	decr_timecounter.tc_frequency = ticks_per_sec;
 	tc_init(&decr_timecounter);
+	decr_et.et_name = "decrementer";
+	decr_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
+	    ET_FLAGS_PERCPU;
+	decr_et.et_quality = 1000;
+	decr_et.et_frequency = ticks_per_sec;
+	decr_et.et_min_period.sec = 0;
+	decr_et.et_min_period.frac =
+	    ((0x00000002LLU << 32) / ticks_per_sec) << 32;
+	decr_et.et_max_period.sec = 0xfffffffeLLU / ticks_per_sec;
+	decr_et.et_max_period.frac =
+	    ((0xfffffffeLLU << 32) / ticks_per_sec) << 32;
+	decr_et.et_start = decr_et_start;
+	decr_et.et_stop = decr_et_stop;
+	decr_et.et_priv = NULL;
+	et_register(&decr_et);
 }
 
+/*
+ * Event timer start method.
+ */
+static int
+decr_et_start(struct eventtimer *et,
+    struct bintime *first, struct bintime *period)
+{
+	struct decr_state *s = DPCPU_PTR(decr_state);
+	uint32_t fdiv, tcr;
+
+	if (period != NULL) {
+		s->mode = 1;
+		s->div = (decr_et.et_frequency * (period->frac >> 32)) >> 32;
+		if (period->sec != 0)
+			s->div += decr_et.et_frequency * period->sec;
+	} else {
+		s->mode = 2;
+		s->div = 0xffffffff;
+	}
+	if (first != NULL) {
+		fdiv = (decr_et.et_frequency * (first->frac >> 32)) >> 32;
+		if (first->sec != 0)
+			fdiv += decr_et.et_frequency * first->sec;
+	} else
+		fdiv = s->div;
+
+	tcr = mfspr(SPR_TCR);
+	tcr |= TCR_DIE;
+	if (s->mode == 1) {
+		mtspr(SPR_DECAR, s->div);
+		tcr |= TCR_ARE;
+	} else
+		tcr &= ~TCR_ARE;
+	mtdec(fdiv);
+	mtspr(SPR_TCR, tcr);
+	return (0);
+}
+
+/*
+ * Event timer stop method.
+ */
+static int
+decr_et_stop(struct eventtimer *et)
+{
+	struct decr_state *s = DPCPU_PTR(decr_state);
+	uint32_t tcr;
+
+	s->mode = 0;
+	s->div = 0xffffffff;
+	tcr = mfspr(SPR_TCR);
+	tcr &= ~(TCR_DIE | TCR_ARE);
+	mtspr(SPR_TCR, tcr);
+	return (0);
+}
+
+/*
+ * Timecounter get method.
+ */
 static unsigned
 decr_get_timecount(struct timecounter *tc)
 {
@@ -203,18 +287,3 @@ DELAY(int n)
 	} while (now < end || (now > start && end < start));
 }
 
-/*
- * Nothing to do.
- */
-void
-cpu_startprofclock(void)
-{
-
-	/* Do nothing */
-}
-
-void
-cpu_stopprofclock(void)
-{
-
-}

Modified: head/sys/powerpc/booke/interrupt.c
==============================================================================
--- head/sys/powerpc/booke/interrupt.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/booke/interrupt.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -116,11 +116,15 @@ void
 powerpc_decr_interrupt(struct trapframe *framep)
 {
 	struct thread *td;
+	struct trapframe *oldframe;
 
 	td = PCPU_GET(curthread);
 	critical_enter();
 	atomic_add_int(&td->td_intr_nesting_level, 1);
+	oldframe = td->td_intr_frame;
+	td->td_intr_frame = framep;
 	decr_intr(framep);
+	td->td_intr_frame = oldframe;
 	atomic_subtract_int(&td->td_intr_nesting_level, 1);
 	critical_exit();
 	framep->srr1 &= ~PSL_WE;

Modified: head/sys/powerpc/booke/platform_bare.c
==============================================================================
--- head/sys/powerpc/booke/platform_bare.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/booke/platform_bare.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -82,7 +82,7 @@ static platform_method_t bare_methods[] 
 	PLATFORMMETHOD(platform_smp_get_bsp,	bare_smp_get_bsp),
 	PLATFORMMETHOD(platform_smp_start_cpu,	bare_smp_start_cpu),
 
-	PLATFORMMETHOD(platform_reset,		e500_reset);
+	PLATFORMMETHOD(platform_reset,		e500_reset),
 
 	{ 0, 0 }
 };

Modified: head/sys/powerpc/include/intr_machdep.h
==============================================================================
--- head/sys/powerpc/include/intr_machdep.h	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/include/intr_machdep.h	Sat Sep 11 04:45:51 2010	(r212453)
@@ -48,6 +48,8 @@ struct trapframe;
 
 driver_filter_t powerpc_ipi_handler;
 
+void	intrcnt_add(const char *name, u_long **countp);
+
 void	powerpc_register_pic(device_t, u_int);
 int	powerpc_ign_lookup(uint32_t pic_id);
 

Modified: head/sys/powerpc/include/md_var.h
==============================================================================
--- head/sys/powerpc/include/md_var.h	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/include/md_var.h	Sat Sep 11 04:45:51 2010	(r212453)
@@ -47,8 +47,6 @@ extern	int	busdma_swi_pending;
 extern	vm_offset_t	kstack0;
 extern	vm_offset_t	kstack0_phys;
 
-extern	u_long	ns_per_tick;
-
 extern	int powerpc_pow_enabled;
 extern	int cacheline_size;
 extern  int hw_direct_map;

Modified: head/sys/powerpc/include/smp.h
==============================================================================
--- head/sys/powerpc/include/smp.h	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/include/smp.h	Sat Sep 11 04:45:51 2010	(r212453)
@@ -36,6 +36,7 @@
 #define	IPI_RENDEZVOUS		2
 #define	IPI_STOP		3
 #define	IPI_STOP_HARD		3
+#define	IPI_HARDCLOCK		4
 
 #ifndef LOCORE
 

Modified: head/sys/powerpc/powerpc/intr_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/intr_machdep.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/powerpc/intr_machdep.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -95,6 +95,7 @@ struct powerpc_intr {
 	device_t pic;
 	u_int	intline;
 	u_int	vector;
+	u_int	cntindex;
 	cpumask_t cpu;
 	enum intr_trigger trig;
 	enum intr_polarity pol;
@@ -106,6 +107,7 @@ struct pic {
 	int ipi_irq;
 };
 
+static u_int intrcnt_index = 0;
 static struct mtx intr_table_lock;
 static struct powerpc_intr *powerpc_intrs[INTR_VECTORS];
 static struct pic piclist[MAX_PICS];
@@ -152,6 +154,16 @@ intrcnt_setname(const char *name, int in
 	    MAXCOMLEN, name);
 }
 
+void
+intrcnt_add(const char *name, u_long **countp)
+{
+	int idx;
+
+	idx = atomic_fetchadd_int(&intrcnt_index, 1);
+	*countp = &intrcnt[idx];
+	intrcnt_setname(name, idx);
+}
+
 static struct powerpc_intr *
 intr_lookup(u_int irq)
 {
@@ -200,8 +212,10 @@ intr_lookup(u_int irq)
 
 	if (iscan == NULL && i->vector != -1) {
 		powerpc_intrs[i->vector] = i;
+		i->cntindex = atomic_fetchadd_int(&intrcnt_index, 1);
+		i->cntp = &intrcnt[i->cntindex];
 		sprintf(intrname, "irq%u:", i->irq);
-		intrcnt_setname(intrname, i->vector);
+		intrcnt_setname(intrname, i->cntindex);
 		nvectors++;
 	}
 	mtx_unlock(&intr_table_lock);
@@ -384,8 +398,6 @@ powerpc_setup_intr(const char *name, u_i
 		if (error)
 			return (error);
 
-		i->cntp = &intrcnt[i->vector];
-
 		enable = 1;
 	}
 
@@ -393,7 +405,7 @@ powerpc_setup_intr(const char *name, u_i
 	    intr_priority(flags), flags, cookiep);
 
 	mtx_lock(&intr_table_lock);
-	intrcnt_setname(i->event->ie_fullname, i->vector);
+	intrcnt_setname(i->event->ie_fullname, i->cntindex);
 	mtx_unlock(&intr_table_lock);
 
 	if (!cold) {

Modified: head/sys/powerpc/powerpc/mp_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c	Sat Sep 11 02:00:27 2010	(r212452)
+++ head/sys/powerpc/powerpc/mp_machdep.c	Sat Sep 11 04:45:51 2010	(r212453)
@@ -59,7 +59,6 @@ extern struct pcpu __pcpu[MAXCPU];
 
 volatile static int ap_awake;
 volatile static u_int ap_letgo;
-volatile static uint32_t ap_decr;
 volatile static u_quad_t ap_timebase;
 static u_int ipi_msg_cnt[32];
 static struct mtx ap_boot_mtx;
@@ -79,9 +78,8 @@ machdep_ap_bootstrap(void)
 		;
 
 	/* Initialize DEC and TB, sync with the BSP values */
-	decr_ap_init();
 	mttb(ap_timebase);
-	__asm __volatile("mtdec %0" :: "r"(ap_decr));
+	decr_ap_init();
 
 	/* Serialize console output and AP count increment */
 	mtx_lock_spin(&ap_boot_mtx);
@@ -96,6 +94,9 @@ machdep_ap_bootstrap(void)
 	/* Let the DEC and external interrupts go */
 	mtmsr(mfmsr() | PSL_EE);
 
+	/* Start per-CPU event timers. */
+	cpu_initclocks_ap();
+
 	/* Announce ourselves awake, and enter the scheduler */
 	sched_throw(NULL);
 }
@@ -243,7 +244,6 @@ cpu_mp_unleash(void *dummy)
 	ap_awake = 1;
 
 	/* Provide our current DEC and TB values for APs */
-	__asm __volatile("mfdec %0" : "=r"(ap_decr));
 	ap_timebase = mftb() + 10;
 	__asm __volatile("msync; isync");
 	
@@ -313,6 +313,10 @@ powerpc_ipi_handler(void *arg)
 			atomic_clear_int(&stopped_cpus, self);
 			CTR1(KTR_SMP, "%s: IPI_STOP (restart)", __func__);
 			break;
+		case IPI_HARDCLOCK:
+			CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__);
+			hardclockintr(curthread->td_intr_frame);
+			break;
 		}
 	}
 


More information about the svn-src-all mailing list