割り込みコントローラへのSMP対応コード

全く動作確認取ってないしコンパイルすら通してないけど、俺のゴーストはこれで大丈夫とささやいてるから多分大体あってるはず。
アクセスするレジスタ類はLinuxのip27のコードに合わせて、interm,imaskの配列化は以前ip30向けに実装したコードを参照。

Index: ip27_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/ip27_machdep.c,v
retrieving revision 1.51
diff -u -p -r1.51 ip27_machdep.c
--- ip27_machdep.c	9 May 2010 18:37:47 -0000	1.51
+++ ip27_machdep.c	21 May 2010 05:58:48 -0000
@@ -108,7 +113,7 @@ struct intrhand *hubpi_intrhand1[HUBPI_N
 
 struct {
 	uint64_t hw[2];
-} hubpi_intem, hubpi_imask[NIPLS];
+} hubpi_intem[MAXCPUS], hubpi_imask[MAXCPUS][NIPLS];
 
 void
 ip27_setup()
@@ -645,12 +663,13 @@ int
 ip27_hub_intr_register(int widget, int level, int *intrbit)
 {
 	int bit;
+	u_long cpuid = cpu_number();
 
 	/*
 	 * Try to allocate a bit on hardware level 0 first.
 	 */
 	for (bit = HUBPI_INTR0_WIDGET_MAX; bit >= HUBPI_INTR0_WIDGET_MIN; bit--)
-		if ((hubpi_intem.hw[0] & (1UL << bit)) == 0)
+		if ((hubpi_intem[cpuid].hw[0] & (1UL << bit)) == 0)
 			goto found;
 
 	/*
@@ -806,21 +825,25 @@ ip27_hub_splx(int newipl)
 
 #define	INTR_FUNCTIONNAME	hubpi_intr0
 #define	MASK_FUNCTIONNAME	ip27_hub_intr_makemasks0
-#define	INTR_LOCAL_DECLS
-#define	MASK_LOCAL_DECLS
+#define	INTR_LOCAL_DECLS \
+	u_long cpuid = cpu_number();
+#define	MASK_LOCAL_DECLS \
+	u_long cpuid = cpu_number();
 #define	INTR_GETMASKS \
 do { \
-	/* XXX this assumes we run on cpu0 */ \
+	int cpu = curcpu()->ci_hw.physid; \
 	isr = IP27_LHUB_L(HUBPI_IR0); \
-	imr = IP27_LHUB_L(HUBPI_CPU0_IMR0); \
+	imr = IP27_LHUB_L(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0); \
 	bit = HUBPI_INTR0_WIDGET_MAX; \
 } while (0)
 #define	INTR_MASKPENDING \
 do { \
-	IP27_LHUB_S(HUBPI_CPU0_IMR0, imr & ~isr); \
+	int cpu = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0, \
+		imr & ~isr); \
 	(void)IP27_LHUB_L(HUBPI_IR0); \
 } while (0)
-#define	INTR_IMASK(ipl)		hubpi_imask[ipl].hw[0]
+#define	INTR_IMASK(ipl)		hubpi_imask[cpuid][ipl].hw[0]
 #define	INTR_HANDLER(bit)	hubpi_intrhand0[bit]
 #define	INTR_SPURIOUS(bit) \
 do { \
@@ -828,7 +851,8 @@ do { \
 } while (0)
 #define	INTR_MASKRESTORE \
 do { \
-	IP27_LHUB_S(HUBPI_CPU0_IMR0, imr); \
+	int cpu = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0, imr); \
 	(void)IP27_LHUB_L(HUBPI_IR0); \
 } while (0)
 #define	INTR_MASKSIZE	HUBPI_NINTS
@@ -837,21 +861,25 @@ do { \
 
 #define	INTR_FUNCTIONNAME	hubpi_intr1
 #define	MASK_FUNCTIONNAME	ip27_hub_intr_makemasks1
-#define	INTR_LOCAL_DECLS
-#define	MASK_LOCAL_DECLS
+#define	INTR_LOCAL_DECLS \
+	u_long cpuid = cpu_number();
+#define	MASK_LOCAL_DECLS \
+	u_long cpuid = cpu_number();
 #define	INTR_GETMASKS \
 do { \
-	/* XXX this assumes we run on cpu0 */ \
+	int cpu = curcpu()->ci_hw.physid; \
 	isr = IP27_LHUB_L(HUBPI_IR1); \
-	imr = IP27_LHUB_L(HUBPI_CPU0_IMR1); \
+	imr = IP27_LHUB_L(cpuid == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1); \
 	bit = HUBPI_INTR1_WIDGET_MAX; \
 } while (0)
 #define	INTR_MASKPENDING \
 do { \
-	IP27_LHUB_S(HUBPI_CPU0_IMR1, imr & ~isr); \
+	int cpu = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, \
+		imr & ~isr); \
 	(void)IP27_LHUB_L(HUBPI_IR1); \
 } while (0)
-#define	INTR_IMASK(ipl)		hubpi_imask[ipl].hw[1]
+#define	INTR_IMASK(ipl)		hubpi_imask[cpuid][ipl].hw[1]
 #define	INTR_HANDLER(bit)	hubpi_intrhand1[bit]
 #define	INTR_SPURIOUS(bit) \
 do { \
@@ -859,7 +887,8 @@ do { \
 } while (0)
 #define	INTR_MASKRESTORE \
 do { \
-	IP27_LHUB_S(HUBPI_CPU0_IMR1, imr); \
+	int cpu = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1, imr); \
 	(void)IP27_LHUB_L(HUBPI_IR1); \
 } while (0)
 #define	INTR_MASKSIZE	HUBPI_NINTS
@@ -869,12 +898,13 @@ do { \
 void
 ip27_hub_setintrmask(int level)
 {
-	/* XXX this assumes we run on cpu0 */
-	IP27_LHUB_S(HUBPI_CPU0_IMR0,
-	    hubpi_intem.hw[0] & ~hubpi_imask[level].hw[0]);
+	int cpu = curcpu()->ci_hw.physid;
+	u_long cpuid = cpu_number();
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR0 : HUBPI_CPU1_IMR0,
+	    hubpi_intem[cpuid].hw[0] & ~hubpi_imask[cpuid][level].hw[0]);
 	(void)IP27_LHUB_L(HUBPI_IR0);
-	IP27_LHUB_S(HUBPI_CPU0_IMR1,
-	    hubpi_intem.hw[1] & ~hubpi_imask[level].hw[1]);
+	IP27_LHUB_S(cpu == 0 ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1,
+	    hubpi_intem[cpuid].hw[1] & ~hubpi_imask[cpuid][level].hw[1]);
 	(void)IP27_LHUB_L(HUBPI_IR1);
 }