cpu1にIPIがかからないずら。

現状:

  • cpu1でクロック割り込みはかかる
  • cpu0→cpu0のIPIはかかる
  • cpu1→cpu0のIPIはかかる
  • cpu1→cpu1のIPIはかからない
  • cpu0→cpu1のIPIはかからない

何となく、割り込みコントローラへの設定などなどがしくってるような気がするけど、IMR0の値もステータスレジスタの値も一見正しく見えるし、どこが悪いのか良く分からない。
実はIRQが違うとか?
そしてコミット出来ぬまま太り続けるパッチ。

Index: mips64/include/autoconf.h
===================================================================
RCS file: /cvs/src/sys/arch/mips64/include/autoconf.h,v
retrieving revision 1.1
diff -u -p -r1.1 autoconf.h
--- mips64/include/autoconf.h	9 Jan 2010 20:33:16 -0000	1.1
+++ mips64/include/autoconf.h	31 May 2010 14:20:54 -0000
@@ -30,6 +30,6 @@ struct cpu_attach_args {
 	struct cpu_hwinfo		*caa_hw;
 };
 
-extern struct cpu_hwinfo bootcpu_hwinfo;
+extern struct cpu_hwinfo cpu_hwinfo[MAXCPUS];
 
 #endif /* _MIPS64_AUTOCONF_H_ */
Index: mips64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v
retrieving revision 1.58
diff -u -p -r1.58 cpu.h
--- mips64/include/cpu.h	28 Apr 2010 16:20:28 -0000	1.58
+++ mips64/include/cpu.h	31 May 2010 14:20:55 -0000
@@ -370,6 +370,10 @@ struct cpu_hwinfo {
 	uint32_t	tlbsize;
 	uint		type;
 	uint32_t	l2size;
+#ifdef TGT_ORIGIN
+	int		nasid;
+	int		physid;
+#endif
 };
 
 struct cpu_info {
Index: mips64/mips64/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/clock.c,v
retrieving revision 1.33
diff -u -p -r1.33 clock.c
--- mips64/mips64/clock.c	28 Feb 2010 17:23:25 -0000	1.33
+++ mips64/mips64/clock.c	31 May 2010 14:20:55 -0000
@@ -194,7 +194,7 @@ delay(int n)
 
 	delayconst = ci->ci_delayconst;
 	if (delayconst == 0)
-		delayconst = bootcpu_hwinfo.clock / 2;
+		delayconst = cpu_hwinfo[cpu_number()].clock / 2;
 	p = cp0_get_count();
 	dly = (delayconst / 1000000) * n;
 	while (dly > 0) { 
Index: sgi/include/intr.h
===================================================================
RCS file: /cvs/src/sys/arch/sgi/include/intr.h,v
retrieving revision 1.41
diff -u -p -r1.41 intr.h
--- sgi/include/intr.h	18 Jan 2010 16:59:23 -0000	1.41
+++ sgi/include/intr.h	31 May 2010 14:20:56 -0000
@@ -190,6 +190,8 @@ void	dosoftint(void);
 #ifdef MULTIPROCESSOR
 #if defined (TGT_OCTANE)
 #define ENABLEIPI() updateimask(~CR_INT_2) /* enable IPI interrupt level */
+#elif defined (TGT_ORIGIN)
+#define ENABLEIPI() updateimask(~CR_INT_0) /* enable IPI interrupt level */
 #else
 #error MULTIPROCESSOR kernel not supported on this configuration
 #endif
Index: sgi/sgi/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
--- sgi/sgi/ip27_machdep.c	9 May 2010 18:37:47 -0000	1.51
+++ sgi/sgi/ip27_machdep.c	31 May 2010 14:20:56 -0000
@@ -28,6 +28,7 @@
 #include <sys/malloc.h>
 #include <sys/reboot.h>
 #include <sys/tty.h>
+#include <sys/proc.h>
 
 #include <mips64/arcbios.h>
 #include <mips64/archtype.h>
@@ -56,6 +57,7 @@ extern char *hw_prod;
 
 extern void (*md_halt)(int);
 
+
 paddr_t	ip27_widget_short(int16_t, u_int);
 paddr_t	ip27_widget_long(int16_t, u_int);
 paddr_t	ip27_widget_map(int16_t, u_int,bus_addr_t *, bus_size_t *);
@@ -108,7 +110,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()
@@ -297,6 +299,10 @@ ip27_setup()
 void
 ip27_autoconf(struct device *parent)
 {
+#ifdef MULTIPROCESSOR
+	int cpuid;
+#endif
+
 	union {
 		struct mainbus_attach_args maa;
 		struct cpu_attach_args caa;
@@ -313,11 +319,20 @@ ip27_autoconf(struct device *parent)
 	bzero(&u, sizeof u);
 	u.maa.maa_name = "cpu";
 	u.maa.maa_nasid = currentnasid = masternasid;
-	u.caa.caa_hw = &bootcpu_hwinfo;
+	u.caa.caa_hw = &cpu_hwinfo[0];
 	config_found(parent, &u, ip27_print);
 	u.maa.maa_name = "clock";
 	config_found(parent, &u, ip27_print);
-
+#ifdef MULTIPROCESSOR
+	for (cpuid = 1; cpuid < MAXCPUS; cpuid++)
+		if (cpu_hwinfo[cpuid].clock != 0 
+		&& cpu_hwinfo[cpuid].nasid == currentnasid) {
+			u.maa.maa_name = "cpu";
+			u.maa.maa_nasid = currentnasid;
+			u.caa.caa_hw = &cpu_hwinfo[cpuid];
+			config_found(parent, &u, ip27_print);
+		}
+#endif
 	/*
 	 * Now attach all nodes' I/O devices.
 	 */
@@ -645,12 +660,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;
 
 	/*
@@ -658,7 +674,7 @@ ip27_hub_intr_register(int widget, int l
 	 * level 1.
 	 */
 	for (bit = HUBPI_INTR1_WIDGET_MAX; bit >= HUBPI_INTR1_WIDGET_MIN; bit--)
-		if ((hubpi_intem.hw[1] & (1UL << bit)) == 0) {
+		if ((hubpi_intem[cpuid].hw[1] & (1UL << bit)) == 0) {
 			bit += HUBPI_NINTS;
 			goto found;
 		}
@@ -679,6 +695,7 @@ ip27_hub_intr_establish(int (*func)(void
 {
 	struct intrhand *ih, **anchor;
 	int s;
+	u_long cpuid = cpu_number();
 
 #ifdef DIAGNOSTIC
 	if (intrbit < 0 || intrbit >= HUBPI_NINTS + HUBPI_NINTS)
@@ -723,7 +740,8 @@ ip27_hub_intr_establish(int (*func)(void
 
 	*anchor = ih;
 
-	hubpi_intem.hw[intrbit / HUBPI_NINTS] |= 1UL << (intrbit % HUBPI_NINTS);
+	hubpi_intem[cpuid].hw[intrbit / HUBPI_NINTS]
+		|= 1UL << (intrbit % HUBPI_NINTS);
 	if (intrbit / HUBPI_NINTS != 0)
 		ip27_hub_intr_makemasks1();
 	else
@@ -739,6 +757,7 @@ ip27_hub_intr_disestablish(int intrbit)
 {
 	struct intrhand *ih, **anchor;
 	int s;
+	u_long cpuid = cpu_number();
 
 #ifdef DIAGNOSTIC
 	if (intrbit < 0 || intrbit >= HUBPI_NINTS + HUBPI_NINTS)
@@ -759,7 +778,7 @@ ip27_hub_intr_disestablish(int intrbit)
 
 	*anchor = NULL;
 
-	hubpi_intem.hw[intrbit / HUBPI_NINTS] &=
+	hubpi_intem[cpuid].hw[intrbit / HUBPI_NINTS] &=
 	    ~(1UL << (intrbit % HUBPI_NINTS));
 	if (intrbit / HUBPI_NINTS != 0)
 		ip27_hub_intr_makemasks1();
@@ -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 physid = curcpu()->ci_hw.physid; \
 	isr = IP27_LHUB_L(HUBPI_IR0); \
-	imr = IP27_LHUB_L(HUBPI_CPU0_IMR0); \
+	imr = IP27_LHUB_L(!physid ? 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 physid = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \
 	isr = IP27_LHUB_L(HUBPI_IR1); \
-	imr = IP27_LHUB_L(HUBPI_CPU0_IMR1); \
+	imr = IP27_LHUB_L(!physid ? 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 physid = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid; \
+	IP27_LHUB_S(!physid ? 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 physid = curcpu()->ci_hw.physid;
+	u_long cpuid = cpu_number();
+	IP27_LHUB_S(!physid ? 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(!physid ? HUBPI_CPU0_IMR1 : HUBPI_CPU1_IMR1,
+	    hubpi_intem[cpuid].hw[1] & ~hubpi_imask[cpuid][level].hw[1]);
 	(void)IP27_LHUB_L(HUBPI_IR1);
 }
 
@@ -919,3 +949,142 @@ ip27_nmi(void *arg)
 	printf("Resetting system...\n");
 	boot(RB_USERREQ);
 }
+
+#ifdef MULTIPROCESSOR
+void	build_trampoline(vaddr_t, vaddr_t);
+
+#define LAUNCH_SLAVE \
+	(*(void (*)(int nasid, int cpu, void *call_addr, uint64_t call_parm, \
+	void *stack_addr, void *gp_addr)) PHYS_TO_CKSEG1(0x1fc00038))
+
+void
+hw_cpu_boot_secondary(struct cpu_info *ci)
+{
+	vaddr_t kstack;
+
+	kstack = alloc_contiguous_pages(USPACE);
+	if (kstack == NULL)
+		panic("unable to allocate idle stack\n");
+	ci->ci_curprocpaddr = (void *)kstack;
+
+	LAUNCH_SLAVE(ci->ci_hw.nasid, ci->ci_hw.physid, 
+		hw_cpu_spinup_trampoline, (uint64_t)ci, 
+		(void *)(kstack + USPACE), 0);
+
+	while (!cpuset_isset(&cpus_running, ci))
+		;
+}
+
+void
+hw_cpu_hatch(struct cpu_info *ci)
+{
+	int s;
+	vaddr_t xtlb_handler;
+	extern char exception[], e_exception[];
+
+	/*
+	 * Set curcpu address on this processor.
+	 */
+	setcurcpu(ci);
+
+	/*
+	 * Make sure we can access the extended address space.
+	 * Note that r10k and later do not allow XUSEG accesses
+	 * from kernel mode unless SR_UX is set.
+	 */
+	setsr(getsr() | SR_KX | SR_UX);
+
+	tlb_set_page_mask(TLB_PAGE_MASK);
+	tlb_set_wired(0);
+	tlb_flush(64);
+	tlb_set_wired(UPAGES / 2);
+
+	tlb_set_pid(0);
+
+	/*
+	 * Copy down exception vector code.
+	 */
+	bcopy(exception, (char *)CACHE_ERR_EXC_VEC, e_exception - exception);
+	bcopy(exception, (char *)GEN_EXC_VEC, e_exception - exception);
+
+	/*
+	 * Build proper TLB refill handler trampolines.
+	 */
+	extern void xtlb_miss;
+	xtlb_handler = (vaddr_t)&xtlb_miss;
+
+	build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler);
+	build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler);
+
+	/*
+	 * Turn off bootstrap exception vectors.
+	 */
+	setsr(getsr() & ~SR_BOOT_EXC_VEC);
+
+	/*
+	 * Clear out the I and D caches.
+	 */
+	Mips10k_ConfigCache(ci);
+	Mips_SyncCache(ci);
+	
+	cpu_startclock(ci);
+	ncpus++;
+	cpuset_add(&cpus_running, ci);
+	mips64_ipi_init();
+	ip27_hub_setintrmask(0);
+	spl0();
+	(void)updateimask(0);
+
+#ifdef DEBUG
+	printf("imr0: %x\n",
+		IP27_LHUB_L(HUBPI_CPU1_IMR0));
+	printf("sr: %x\n",
+		getsr());
+#endif
+
+	SCHED_LOCK(s);
+	cpu_switchto(NULL, sched_chooseproc());
+}
+
+int
+hw_ipi_intr_establish(int (*func)(void *), u_long cpuid)
+{
+	int physid = get_cpu_info(cpuid)->ci_hw.physid;
+	int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B;
+
+#ifdef DEBUG
+	printf("hw_ipi_intr_establish(%d)\n", cpuid);
+#endif
+	ip27_hub_intr_establish(func, (void *)cpuid, level,
+		IPL_IPI, NULL, &curcpu()->ci_ipiih);
+
+	return 0;
+};
+
+void
+hw_ipi_intr_set(u_long cpuid)
+{
+	int physid = get_cpu_info(cpuid)->ci_hw.physid;
+	int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B;
+
+#ifdef DEBUG
+	printf("hw_ipi_intr_set(%d)\n", cpuid);
+#endif
+
+	ip27_hub_intr_set(level);
+}
+
+void
+hw_ipi_intr_clear(u_long cpuid)
+{
+	int physid = get_cpu_info(cpuid)->ci_hw.physid;
+	int level = !physid ? HUBPI_ISR0_CPU_ACTION_A : HUBPI_ISR0_CPU_ACTION_B;
+
+#ifdef DEBUG
+	printf("hw_ipi_intr_clear(%d)\n", cpuid);
+#endif
+
+	ip27_hub_intr_clear(level);
+}
+
+#endif
Index: sgi/sgi/ip30_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/ip30_machdep.c,v
retrieving revision 1.42
diff -u -p -r1.42 ip30_machdep.c
--- sgi/sgi/ip30_machdep.c	28 Apr 2010 16:20:28 -0000	1.42
+++ sgi/sgi/ip30_machdep.c	31 May 2010 14:20:56 -0000
@@ -160,14 +160,14 @@ ip30_setup()
 	xbow_widget_map = ip30_widget_map;
 	xbow_widget_id = ip30_widget_id;
 
-	bootcpu_hwinfo.c0prid = cp0_get_prid();
-	bootcpu_hwinfo.c1prid = cp1_get_prid();
+	cpu_hwinfo[0].c0prid = cp0_get_prid();
+	cpu_hwinfo[0].c1prid = cp1_get_prid();
 	cpuspeed = bios_getenvint("cpufreq");
 	if (cpuspeed < 100)
 		cpuspeed = 175;		/* reasonable default */
-	bootcpu_hwinfo.clock = cpuspeed * 1000000;
-	bootcpu_hwinfo.tlbsize = 64;	/* R10000 family */
-	bootcpu_hwinfo.type = (bootcpu_hwinfo.c0prid >> 8) & 0xff;
+	cpu_hwinfo[0].clock = cpuspeed * 1000000;
+	cpu_hwinfo[0].tlbsize = 64;	/* R10000 family */
+	cpu_hwinfo[0].type = (cpu_hwinfo[0].c0prid >> 8) & 0xff;
 
 	/*
 	 * Initialize the early console parameters.
@@ -232,7 +232,7 @@ ip30_autoconf(struct device *parent)
 	bzero(&caa, sizeof caa);
 	caa.caa_maa.maa_nasid = masternasid;
 	caa.caa_maa.maa_name = "cpu";
-	caa.caa_hw = &bootcpu_hwinfo;
+	caa.caa_hw = &cpu_hwinfo[0];
 	config_found(parent, &caa, mbprint);
 
 #ifdef MULTIPROCESSOR
@@ -245,7 +245,7 @@ ip30_autoconf(struct device *parent)
 			 * since Octane processors should be identical
 			 * (model, speed and cache), this should be safe.
 			 */
-			bcopy(&bootcpu_hwinfo, &hw, sizeof(struct cpu_hwinfo));
+			bcopy(&cpu_hwinfo[0], &hw, sizeof(struct cpu_hwinfo));
 			hw.c0prid = 
 		           *(volatile uint32_t *)(mpconf + MPCONF_PRID(cpuid));
 			hw.type = (hw.c0prid >> 8) & 0xff;
Index: sgi/sgi/ip32_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/ip32_machdep.c,v
retrieving revision 1.15
diff -u -p -r1.15 ip32_machdep.c
--- sgi/sgi/ip32_machdep.c	6 Apr 2010 19:15:29 -0000	1.15
+++ sgi/sgi/ip32_machdep.c	31 May 2010 14:20:57 -0000
@@ -127,18 +127,18 @@ ip32_setup()
 		break;
 	}
 
-	bootcpu_hwinfo.c0prid = cp0_get_prid();
-	bootcpu_hwinfo.c1prid = cp1_get_prid();
+	cpu_hwinfo[0].c0prid = cp0_get_prid();
+	cpu_hwinfo[0].c1prid = cp1_get_prid();
 	cpuspeed = bios_getenvint("cpufreq");
 	if (cpuspeed < 100)
 		cpuspeed = 180;		/* reasonable default */
-	bootcpu_hwinfo.clock = cpuspeed * 1000000;
-	bootcpu_hwinfo.type = (bootcpu_hwinfo.c0prid >> 8) & 0xff;
+	cpu_hwinfo[0].clock = cpuspeed * 1000000;
+	cpu_hwinfo[0].type = (cpu_hwinfo[0].c0prid >> 8) & 0xff;
 
 	/*
 	 * Figure out how many TLB are available.
 	 */
-	switch (bootcpu_hwinfo.type) {
+	switch (cpu_hwinfo[0].type) {
 #ifdef CPU_RM7000
 	case MIPS_RM7000:
 		/*
@@ -162,8 +162,8 @@ ip32_setup()
 		 * the highest valid TLB entry we can find and
 		 * see if it is in the upper 16 entries or not.
 		 */
-		bootcpu_hwinfo.tlbsize = 48;
-		if (((bootcpu_hwinfo.c0prid >> 4) & 0x0f) >= 2) {
+		cpu_hwinfo[0].tlbsize = 48;
+		if (((cpu_hwinfo[0].c0prid >> 4) & 0x0f) >= 2) {
 			struct tlb_entry te;
 			int e, lastvalid;
 
@@ -180,7 +180,7 @@ ip32_setup()
 			}
 			tlb_flush(64);
 			if (lastvalid >= 48)
-				bootcpu_hwinfo.tlbsize = 64;
+				cpu_hwinfo[0].tlbsize = 64;
 		}
 		break;
 #endif
@@ -188,11 +188,11 @@ ip32_setup()
 	case MIPS_R10000:
 	case MIPS_R12000:
 	case MIPS_R14000:
-		bootcpu_hwinfo.tlbsize = 64;
+		cpu_hwinfo[0].tlbsize = 64;
 		break;
 #endif
 	default:	/* R5000, RM52xx */
-		bootcpu_hwinfo.tlbsize = 48;
+		cpu_hwinfo[0].tlbsize = 48;
 		break;
 	}
 
Index: sgi/sgi/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/machdep.c,v
retrieving revision 1.102
diff -u -p -r1.102 machdep.c
--- sgi/sgi/machdep.c	28 Apr 2010 21:26:47 -0000	1.102
+++ sgi/sgi/machdep.c	31 May 2010 14:20:57 -0000
@@ -111,7 +111,7 @@ int16_t	masternasid;
 
 int32_t *environment;
 struct sys_rec sys_config;
-struct cpu_hwinfo bootcpu_hwinfo;
+struct cpu_hwinfo cpu_hwinfo[MAXCPUS];
 
 /* Pointers to the start and end of the symbol table. */
 caddr_t	ssym;
@@ -352,7 +352,7 @@ mips_init(int argc, void *argv, caddr_t 
 	/*
 	 * Configure cache.
 	 */
-	switch (bootcpu_hwinfo.type) {
+	switch (cpu_hwinfo[0].type) {
 #ifdef CPU_R10000
 	case MIPS_R10000:
 	case MIPS_R12000:
@@ -425,7 +425,7 @@ mips_init(int argc, void *argv, caddr_t 
 
 	tlb_set_page_mask(TLB_PAGE_MASK);
 	tlb_set_wired(0);
-	tlb_flush(bootcpu_hwinfo.tlbsize);
+	tlb_flush(cpu_hwinfo[0].tlbsize);
 	tlb_set_wired(UPAGES / 2);
 
 	/*
Index: sgi/sgi/mainbus.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/mainbus.c,v
retrieving revision 1.8
diff -u -p -r1.8 mainbus.c
--- sgi/sgi/mainbus.c	9 Jan 2010 20:33:16 -0000	1.8
+++ sgi/sgi/mainbus.c	31 May 2010 14:20:57 -0000
@@ -96,7 +96,7 @@ mbattach(struct device *parent, struct d
 
 	bzero(&caa, sizeof caa);
 	caa.caa_maa.maa_name = "cpu";
-	caa.caa_hw = &bootcpu_hwinfo;
+	caa.caa_hw = &cpu_hwinfo[0];
 	config_found(self, &caa, mbprint);
 
 	caa.caa_maa.maa_name = "clock";
Index: sgi/sgi/sginode.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/sginode.c,v
retrieving revision 1.19
diff -u -p -r1.19 sginode.c
--- sgi/sgi/sginode.c	6 Apr 2010 19:09:50 -0000	1.19
+++ sgi/sgi/sginode.c	31 May 2010 14:20:57 -0000
@@ -76,6 +76,7 @@ int	kl_n_mode = 0;
 u_int	kl_n_shift = 32;
 klinfo_t *kl_glass_console = NULL;
 
+
 void
 kl_init(int ip35)
 {
@@ -249,17 +250,33 @@ kl_first_pass_comp(klinfo_t *comp, void 
 		 * XXX this assumes the first cpu encountered is the boot
 		 * XXX cpu.
 		 */
-		if (bootcpu_hwinfo.clock == 0) {
-			bootcpu_hwinfo.c0prid = cpucomp->cpu_prid;
+		if (cpu_hwinfo[0].clock == 0) {
+			cpu_hwinfo[0].c0prid = cpucomp->cpu_prid;
+			if (ip35)
+				cpu_hwinfo[0].c1prid = cpucomp->cpu_prid;
+			else
+				cpu_hwinfo[0].c1prid = cpucomp->cpu_fpirr;
+			cpu_hwinfo[0].clock = cpucomp->cpu_speed * 1000000;
+			cpu_hwinfo[0].tlbsize = 64;
+			cpu_hwinfo[0].type = (cpucomp->cpu_prid >> 8) & 0xff;
+			cpu_hwinfo[0].nasid = comp->nasid;
+			cpu_hwinfo[0].physid = comp->physid;
+		} else {
+#ifdef MULTIPROCESSOR
+			int cpuid = ncpusfound;
+			cpu_hwinfo[cpuid].c0prid = cpucomp->cpu_prid;
 			if (ip35)
-				bootcpu_hwinfo.c1prid = cpucomp->cpu_prid;
+				cpu_hwinfo[cpuid].c1prid = cpucomp->cpu_prid;
 			else
-				bootcpu_hwinfo.c1prid = cpucomp->cpu_fpirr;
-			bootcpu_hwinfo.clock = cpucomp->cpu_speed * 1000000;
-			bootcpu_hwinfo.tlbsize = 64;
-			bootcpu_hwinfo.type = (cpucomp->cpu_prid >> 8) & 0xff;
-		} else
+				cpu_hwinfo[cpuid].c1prid = cpucomp->cpu_fpirr;
+			cpu_hwinfo[cpuid].clock = cpucomp->cpu_speed * 1000000;
+		        cpu_hwinfo[cpuid].tlbsize = 64;
+			cpu_hwinfo[cpuid].type = (cpucomp->cpu_prid >> 8) & 0xff;
+			cpu_hwinfo[cpuid].nasid = comp->nasid;
+			cpu_hwinfo[cpuid].physid = comp->physid;
+#endif
 			ncpusfound++;
+		}
 		break;
 
 	case KLSTRUCT_MEMBNK:
Index: sgi/xbow/hub.h
===================================================================
RCS file: /cvs/src/sys/arch/sgi/xbow/hub.h,v
retrieving revision 1.7
diff -u -p -r1.7 hub.h
--- sgi/xbow/hub.h	8 Nov 2009 22:44:16 -0000	1.7
+++ sgi/xbow/hub.h	31 May 2010 14:20:57 -0000
@@ -145,7 +145,9 @@
 /* 35-0 available */
 
 /** Level 0 interrupt */
-/* 63-7 available */
+/* 63-9 available */
+#define HUBPI_ISR0_CPU_ACTION_B		8
+#define HUBPI_ISR0_CPU_ACTION_A		7
 /* IPI interrupts */
 #define	HUBPI_ISR0_IPI_B		6
 #define	HUBPI_ISR0_IPI_A		5