PERFORCE change 130726 for review

Marcel Moolenaar marcel at FreeBSD.org
Wed Dec 12 11:19:37 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=130726

Change 130726 by marcel at marcel_cluster on 2007/12/12 19:19:01

	Add rudimentary support for IPIs. Since there are only 4
	IPI "channels" and we typically have more than 4 IPI
	messages, we use a bitmap approach where each IPI message
	corresponds to a bit in pcpu->pc_ipimask and we always
	raise the IPI using a single channel (channel 0). This
	way we support up to 32 IPI messages and don't care that
	IPIs are not queued to the processor.
	
	This changes the OpenPIC driver to always use the private
	per-processor register bank instead of the global one.
	
	The PIC I/F also grows a new method, called ipi().

Affected files ...

.. //depot/projects/powerpc/sys/powerpc/include/openpicreg.h#4 edit
.. //depot/projects/powerpc/sys/powerpc/include/openpicvar.h#4 edit
.. //depot/projects/powerpc/sys/powerpc/include/pcpu.h#8 edit
.. //depot/projects/powerpc/sys/powerpc/powermac/openpic_macio.c#3 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#11 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/openpic.c#4 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/pic_if.m#4 edit
.. //depot/projects/powerpc/sys/powerpc/psim/openpic_iobus.c#3 edit

Differences ...

==== //depot/projects/powerpc/sys/powerpc/include/openpicreg.h#4 (text+ko) ====

@@ -33,16 +33,35 @@
 #define	OPENPIC_SIZE			0x40000
 
 /*
- * GLOBAL/TIMER register (IDU base + 0x1000)
+ * Per Processor Registers [private access] (0x00000 - 0x00fff)
+ */
+
+/* IPI dispatch command reg */
+#define	OPENPIC_IPI_DISPATCH(ipi)	(0x40 + (ipi) * 0x10)
+
+/* current task priority reg */
+#define	OPENPIC_PRIORITY		0x80
+#define  OPENPIC_PRIORITY_MASK			0x0000000f
+
+#define	OPENPIC_WHOAMI			0x90
+
+/* interrupt acknowledge reg */
+#define	OPENPIC_IACK			0xa0
+
+/* end of interrupt reg */
+#define	OPENPIC_EOI			0xb0
+
+/*
+ * Global registers (0x01000-0x0ffff)
  */
 
 /* feature reporting reg 0 */
 #define OPENPIC_FEATURE			0x1000
-#define	OPENPIC_FEATURE_VERSION_MASK	0x000000ff
-#define	OPENPIC_FEATURE_LAST_CPU_MASK	0x00001f00
-#define	OPENPIC_FEATURE_LAST_CPU_SHIFT	8
-#define	OPENPIC_FEATURE_LAST_IRQ_MASK	0x07ff0000
-#define	OPENPIC_FEATURE_LAST_IRQ_SHIFT	16
+#define	 OPENPIC_FEATURE_VERSION_MASK		0x000000ff
+#define	 OPENPIC_FEATURE_LAST_CPU_MASK		0x00001f00
+#define	 OPENPIC_FEATURE_LAST_CPU_SHIFT		8
+#define	 OPENPIC_FEATURE_LAST_IRQ_MASK		0x07ff0000
+#define	 OPENPIC_FEATURE_LAST_IRQ_SHIFT		16
 
 /* global config reg 0 */
 #define OPENPIC_CONFIG			0x1020
@@ -51,9 +70,9 @@
 
 /* interrupt configuration mode (direct or serial) */
 #define OPENPIC_ICR			0x1030
-#define  OPENPIC_ICR_SERIAL_MODE	(1 << 27)
-#define  OPENPIC_ICR_SERIAL_RATIO_MASK	(0x7 << 28)
-#define  OPENPIC_ICR_SERIAL_RATIO_SHIFT	28
+#define  OPENPIC_ICR_SERIAL_MODE		(1 << 27)
+#define  OPENPIC_ICR_SERIAL_RATIO_MASK		(0x7 << 28)
+#define  OPENPIC_ICR_SERIAL_RATIO_SHIFT		28
 
 /* vendor ID */
 #define OPENPIC_VENDOR_ID		0x1080
@@ -67,9 +86,16 @@
 /* spurious intr. vector */
 #define OPENPIC_SPURIOUS_VECTOR		0x10e0
 
+/* Timer registers */
+#define	OPENPIC_TIMERS			4
+#define	OPENPIC_TFREQ			0x10f0
+#define	OPENPIC_TCNT(t)			(0x1100 + (t) * 0x40)
+#define	OPENPIC_TBASE(t)		(0x1110 + (t) * 0x40)
+#define	OPENPIC_TVEC(t)			(0x1120 + (t) * 0x40)
+#define	OPENPIC_TDST(t)			(0x1130 + (t) * 0x40)
 
 /*
- * INTERRUPT SOURCE register (IDU base + 0x10000)
+ * Interrupt Source Configuration Registers (0x10000 - 0x1ffff)
  */
 
 /* interrupt vector/priority reg */
@@ -92,18 +118,20 @@
 #endif
 
 /*
- * PROCESSOR register (IDU base + 0x20000)
+ * Per Processor Registers [global access] (0x20000 - 0x3ffff)
  */
 
-/* IPI command reg */
-#define OPENPIC_IPI(cpu, ipi)		(0x20040 + (cpu) * 0x1000 + (ipi))
+#define	OPENPIC_PCPU_BASE(cpu)		(0x20000 + (cpu) * 0x1000)
+
+#define	OPENPIC_PCPU_IPI_DISPATCH(cpu, ipi)	\
+	(OPENPIC_PCPU_BASE(cpu) + OPENPIC_IPI_DISPATCH(ipi))
+
+#define	OPENPIC_PCPU_PRIORITY(cpu)		\
+	(OPENPIC_PCPU_BASE(cpu) + OPENPIC_PRIORITY)
 
-/* current task priority reg */
-#define OPENPIC_CPU_PRIORITY(cpu)	(0x20080 + (cpu) * 0x1000)
-#define  OPENPIC_CPU_PRIORITY_MASK		0x0000000f
+#define OPENPIC_PCPU_IACK(cpu)			\
+	(OPENPIC_PCPU_BASE(cpu) + OPENPIC_IACK)
 
-/* interrupt acknowledge reg */
-#define OPENPIC_IACK(cpu)		(0x200a0 + (cpu) * 0x1000)
+#define OPENPIC_PCPU_EOI(cpu)			\
+	(OPENPIC_PCPU_BASE(cpu) + OPENPIC_EOI)
 
-/* end of interrupt reg */
-#define OPENPIC_EOI(cpu)		(0x200b0 + (cpu) * 0x1000)

==== //depot/projects/powerpc/sys/powerpc/include/openpicvar.h#4 (text+ko) ====

@@ -57,6 +57,7 @@
 void	openpic_dispatch(device_t, struct trapframe *);
 void	openpic_enable(device_t, u_int, u_int);
 void	openpic_eoi(device_t, u_int);
+void	openpic_ipi(device_t, u_int);
 void	openpic_mask(device_t, u_int);
 void	openpic_unmask(device_t, u_int);
 

==== //depot/projects/powerpc/sys/powerpc/include/pcpu.h#8 (text+ko) ====

@@ -42,6 +42,7 @@
 	struct thread   *pc_fputhread;          /* current fpu user */  \
 	int		pc_bsp:1;					\
 	int		pc_awake:1;					\
+	uint32_t	pc_ipimask;					\
 	register_t	pc_tempsave[CPUSAVE_LEN];			\
 	register_t	pc_disisave[CPUSAVE_LEN];			\
 	register_t	pc_dbsave[CPUSAVE_LEN];

==== //depot/projects/powerpc/sys/powerpc/powermac/openpic_macio.c#3 (text+ko) ====

@@ -70,6 +70,7 @@
 	DEVMETHOD(pic_dispatch,		openpic_dispatch),
 	DEVMETHOD(pic_enable,		openpic_enable),
 	DEVMETHOD(pic_eoi,		openpic_eoi),
+	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_unmask),
 

==== //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#11 (text+ko) ====

@@ -34,11 +34,14 @@
 #include <sys/smp.h>
 
 #include <machine/bus.h>
+#include <machine/intr_machdep.h>
 #include <machine/smp.h>
 
 #include <dev/ofw/openfirm.h>
 #include <machine/ofw_machdep.h>
 
+#include "pic_if.h"
+
 extern void __start_ap(void *);
 
 MALLOC_DEFINE(M_SMP, "smp", "SMP specific datastructures");
@@ -211,9 +214,9 @@
 static void
 ipi_send(struct pcpu *pc, int ipi)
 {
-	/*
-	 *
-	 */
+
+	atomic_set_32(&pc->pc_ipimask, (1 << ipi));
+	PIC_IPI(pic, pc->pc_cpuid);
 }
 
 /* Send an IPI to a set of cpus. */

==== //depot/projects/powerpc/sys/powerpc/powerpc/openpic.c#4 (text+ko) ====

@@ -66,14 +66,14 @@
 }
 
 static __inline void
-openpic_set_priority(struct openpic_softc *sc, int cpu, int pri)
+openpic_set_priority(struct openpic_softc *sc, int pri)
 {
 	uint32_t x;
 
-	x = openpic_read(sc, OPENPIC_CPU_PRIORITY(cpu));
-	x &= ~OPENPIC_CPU_PRIORITY_MASK;
+	x = openpic_read(sc, OPENPIC_PRIORITY);
+	x &= ~OPENPIC_PRIORITY_MASK;
 	x |= pri;
-	openpic_write(sc, OPENPIC_CPU_PRIORITY(cpu), x);
+	openpic_write(sc, OPENPIC_PRIORITY, x);
 }
 
 int
@@ -134,7 +134,7 @@
 	for (irq = 0; irq < sc->sc_nirq; irq++)
 		openpic_write(sc, OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
 
-	openpic_set_priority(sc, 0, 15);
+	openpic_set_priority(sc, 15);
 
 	/* we don't need 8259 passthrough mode */
 	x = openpic_read(sc, OPENPIC_CONFIG);
@@ -157,12 +157,12 @@
 	/* XXX IPI */
 	/* XXX set spurious intr vector */
 
-	openpic_set_priority(sc, 0, 0);
+	openpic_set_priority(sc, 0);
 
 	/* clear all pending interrupts */
 	for (irq = 0; irq < sc->sc_nirq; irq++) {
-		(void)openpic_read(sc, OPENPIC_IACK(0));
-		openpic_write(sc, OPENPIC_EOI(0), 0);
+		(void)openpic_read(sc, OPENPIC_IACK);
+		openpic_write(sc, OPENPIC_EOI, 0);
 	}
 
 	powerpc_register_pic(dev);
@@ -182,7 +182,7 @@
 
 	sc = device_get_softc(dev);
 	while (1) {
-		vector = openpic_read(sc, OPENPIC_IACK(0));
+		vector = openpic_read(sc, OPENPIC_IACK);
 		vector &= OPENPIC_VECTOR_MASK;
 		if (vector == 255)
 			break;
@@ -209,7 +209,16 @@
 	struct openpic_softc *sc;
 
 	sc = device_get_softc(dev);
-	openpic_write(sc, OPENPIC_EOI(0), 0);
+	openpic_write(sc, OPENPIC_EOI, 0);
+}
+
+void
+openpic_ipi(device_t dev, u_int cpu)
+{
+	struct openpic_softc *sc;
+
+	sc = device_get_softc(dev);
+	openpic_write(sc, OPENPIC_IPI_DISPATCH(0), 1u << cpu);
 }
 
 void
@@ -222,7 +231,7 @@
 	x = openpic_read(sc, OPENPIC_SRC_VECTOR(irq));
 	x |= OPENPIC_IMASK;
 	openpic_write(sc, OPENPIC_SRC_VECTOR(irq), x);
-	openpic_write(sc, OPENPIC_EOI(0), 0);
+	openpic_write(sc, OPENPIC_EOI, 0);
 }
 
 void

==== //depot/projects/powerpc/sys/powerpc/powerpc/pic_if.m#4 (text+ko) ====

@@ -48,6 +48,11 @@
 	u_int		irq;
 };
 
+METHOD void ipi {
+	device_t	dev;
+	u_int		cpu;
+};
+
 METHOD void mask {
 	device_t	dev;
 	u_int		irq;

==== //depot/projects/powerpc/sys/powerpc/psim/openpic_iobus.c#3 (text+ko) ====

@@ -74,6 +74,7 @@
 	DEVMETHOD(pic_dispatch,		openpic_dispatch),
 	DEVMETHOD(pic_enable,		openpic_enable),
 	DEVMETHOD(pic_eoi,		openpic_eoi),
+	DEVMETHOD(pic_ipi,		openpic_ipi),
 	DEVMETHOD(pic_mask,		openpic_mask),
 	DEVMETHOD(pic_unmask,		openpic_unmask),
 


More information about the p4-projects mailing list