Module Name:    src
Committed By:   matt
Date:           Mon Mar  1 19:29:42 UTC 2010

Modified Files:
        src/sys/arch/mips/include [matt-nb5-mips64]: cpu.h locore.h
        src/sys/arch/mips/mips [matt-nb5-mips64]: cpu_subr.c genassym.cf
            locore_mips3.S mipsX_subr.S mips_machdep.c

Log Message:
Add secondary processor spinup support (cpu_trampoline is in locore_mips3.S).
Nuke lse_boot_secondary_processors (not needed).
Move cpu_info_store to cpu_subr.C


To generate a diff of this commit:
cvs rdiff -u -r1.90.16.24 -r1.90.16.25 src/sys/arch/mips/include/cpu.h
cvs rdiff -u -r1.78.36.1.2.19 -r1.78.36.1.2.20 \
    src/sys/arch/mips/include/locore.h
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.44.12.20 -r1.44.12.21 src/sys/arch/mips/mips/genassym.cf
cvs rdiff -u -r1.93.38.7 -r1.93.38.8 src/sys/arch/mips/mips/locore_mips3.S
cvs rdiff -u -r1.26.36.1.2.29 -r1.26.36.1.2.30 \
    src/sys/arch/mips/mips/mipsX_subr.S
cvs rdiff -u -r1.205.4.1.2.1.2.39 -r1.205.4.1.2.1.2.40 \
    src/sys/arch/mips/mips/mips_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/include/cpu.h
diff -u src/sys/arch/mips/include/cpu.h:1.90.16.24 src/sys/arch/mips/include/cpu.h:1.90.16.25
--- src/sys/arch/mips/include/cpu.h:1.90.16.24	Sun Feb 28 23:45:07 2010
+++ src/sys/arch/mips/include/cpu.h	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.90.16.24 2010/02/28 23:45:07 matt Exp $	*/
+/*	$NetBSD: cpu.h,v 1.90.16.25 2010/03/01 19:29:41 matt Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -86,11 +86,18 @@
 	vaddr_t ci_pmap_srcbase;	/* starting VA of ephemeral src space */
 	vaddr_t ci_pmap_dstbase;	/* starting VA of ephemeral dst space */
 #ifdef MULTIPROCESSOR
+	volatile u_long ci_flags;
 	uint64_t ci_active_ipis;	/* bitmask of IPIs being serviced */
 	uint32_t ci_ksp_tlb_slot;	/* tlb entry for kernel stack */
 	void *ci_fpsave_si;		/* FP sync softint handler */
 	struct evcnt ci_evcnt_all_ipis;	/* aggregated IPI counter */
 	struct evcnt ci_evcnt_per_ipi[NIPIS];	/* individual IPI counters*/
+
+#define	CPUF_PRIMARY	0x01		/* CPU is primary CPU */
+#define	CPUF_PRESENT	0x02		/* CPU is present */
+#define	CPUF_RUNNING	0x04		/* CPU is running */
+#define	CPUF_PAUSED	0x08		/* CPU is paused */
+#define	CPUF_FPUSAVE	0x10		/* CPU is currently in fpusave_cpu() */
 #endif
 };
 
@@ -400,11 +407,21 @@
 extern int mips_poolpage_vmfreelist;	/* freelist to allocate poolpages */
 
 /* cpu_subr.c */
+#ifdef MULTIPROCESSOR
+extern volatile u_long cpus_running;
+extern volatile u_long cpus_hatched;
+extern volatile u_long cpus_halted;
+#endif
+
 struct cpu_info *
 	cpu_info_alloc(struct pmap_tlb_info *, u_int);
 void	cpu_attach_common(device_t, struct cpu_info *);
 void	cpu_startup_common(void);
-void	cpu_trampoline(struct cpu_info *ci);
+#ifdef MULTIPROCESSOR
+void	cpu_hatch(struct cpu_info *ci);
+void	cpu_trampoline(void);
+void	cpu_boot_secondary_processors(void);
+#endif
 
 /* copy.S */
 int8_t	ufetch_int8(void *);
@@ -506,9 +523,6 @@
 	    const struct phys_ram_seg *, size_t,
 	    const struct mips_vmfreelist *, size_t);
 void	cpu_identify(device_t);
-#ifdef MULTIPROCESSOR
-void	cpu_boot_secondary_processors(void);
-#endif
 
 /* locore*.S */
 int	badaddr(void *, size_t);

Index: src/sys/arch/mips/include/locore.h
diff -u src/sys/arch/mips/include/locore.h:1.78.36.1.2.19 src/sys/arch/mips/include/locore.h:1.78.36.1.2.20
--- src/sys/arch/mips/include/locore.h:1.78.36.1.2.19	Mon Mar  1 19:26:00 2010
+++ src/sys/arch/mips/include/locore.h	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.h,v 1.78.36.1.2.19 2010/03/01 19:26:00 matt Exp $ */
+/* $NetBSD: locore.h,v 1.78.36.1.2.20 2010/03/01 19:29:41 matt Exp $ */
 
 /*
  * This file should not be included by MI code!!!
@@ -347,7 +347,6 @@
 	uintptr_t	lsw_lwp_trampoline;
 	void		(*lsw_cpu_idle)(void);
 	uintptr_t	lsw_setfunc_trampoline;
-	void		(*lsw_boot_secondary_processors)(void);
 	int		(*lsw_send_ipi)(struct cpu_info *, int);
 	void		(*lsw_cpu_offline_md)(void);
 };

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.1.2.1 src/sys/arch/mips/mips/cpu_subr.c:1.1.2.2
--- src/sys/arch/mips/mips/cpu_subr.c:1.1.2.1	Sun Feb 28 23:45:06 2010
+++ src/sys/arch/mips/mips/cpu_subr.c	Mon Mar  1 19:29:41 2010
@@ -32,7 +32,7 @@
 #include "opt_multiprocessor.h"
 #include "opt_sa.h"
 
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.1.2.1 2010/02/28 23:45:06 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.1.2.2 2010/03/01 19:29:41 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -42,6 +42,8 @@
 #include <sys/proc.h>
 #include <sys/user.h>
 #include <sys/ras.h>
+#include <sys/bitops.h>
+#include <sys/idle.h>
 #ifdef KERN_SA
 #include <sys/sa.h>
 #include <sys/savar.h>
@@ -51,11 +53,36 @@
 
 #include <mips/locore.h>
 #include <mips/regnum.h>
+#include <mips/cache.h>
 #include <mips/frame.h>
 #include <mips/userret.h>
+#include <mips/pte.h>
+
+struct cpu_info cpu_info_store
+#ifdef MULTIPROCESSOR
+	__section(".data1")
+	__aligned(1LU << ilog2((2*sizeof(struct cpu_info)-1)))
+#endif
+    = {
+	.ci_curlwp = &lwp0,
+#ifndef NOFPU
+	.ci_fpcurlwp = &lwp0,
+#endif
+	.ci_tlb_info = &pmap_tlb0_info,
+	.ci_pmap_segbase = (void *)(MIPS_KSEG2_START + 0x1eadbeef),
+	.ci_cpl = IPL_HIGH,
+	.ci_tlb_slot = -1,
+#ifdef MULTIPROCESSOR
+	.ci_flags = CPUF_PRIMARY|CPUF_PRESENT|CPUF_RUNNING,
+#endif
+};
 
 #ifdef MULTIPROCESSOR
 
+volatile u_long cpus_running = 1;
+volatile u_long cpus_hatched = 1;
+volatile u_long cpus_paused = 0;
+
 static struct cpu_info *cpu_info_last = &cpu_info_store;
 
 struct cpu_info *
@@ -103,16 +130,13 @@
         ci->ci_divisor_recip = cpu_info_store.ci_divisor_recip;
 
 	/*
-	 * Tail insert this onto the list of cpu_info's.
-	 */
-	KASSERT(ci->ci_next == NULL);
-	KASSERT(cpu_info_last->ci_next == NULL);
-	cpu_info_last->ci_next = ci;
-	cpu_info_last = ci;
-
-	/*
-	 * Attach its TLB 
+	 * Attach its TLB info (which must be direct-mapped)
 	 */
+#ifdef _LP64
+	KASSERT(MIPS_KSEG0_P(ti) || MIPS_XKPHYS_P(ti));
+#else
+	KASSERT(MIPS_KSEG0_P(ti));
+#endif
 	pmap_tlb_info_attach(ti, ci);
 
 #ifndef _LP64
@@ -133,6 +157,12 @@
 
 	mi_cpu_attach(ci);
 
+	/*
+	 * Switch the idle lwp to a direct mapped stack since we use its
+	 * stack and we won't have a TLB entry for it.
+	 */
+	cpu_uarea_remap(ci->ci_data.cpu_idlelwp);
+
 	return ci;
 }
 #endif /* MULTIPROCESSOR */
@@ -147,6 +177,19 @@
 	self->dv_private = ci;
 
 #ifdef MULTIPROCESSOR
+	if (ci != &cpu_info_store) {
+		/*
+		 * Tail insert this onto the list of cpu_info's.
+		 */
+		KASSERT(ci->ci_next == NULL);
+		KASSERT(cpu_info_last->ci_next == NULL);
+		cpu_info_last->ci_next = ci;
+		cpu_info_last = ci;
+	}
+
+	/*
+	 * Initialize IPI framework for this cpu instance
+	 */
 	ipi_init(ci);
 #endif
 
@@ -527,12 +570,77 @@
 }
 
 void
+cpu_hatch(struct cpu_info *ci)
+{
+	struct pmap_tlb_info * const ti = ci->ci_tlb_info;
+	const u_long cpu_mask = 1L << cpu_index(ci);
+
+	/*
+	 * Invalidate all the TLB enties (even wired ones) and then reserve
+	 * space for the wired TLB entries.
+	 */
+	mips3_cp0_wired_write(0);
+	tlb_invalidate_all();
+	mips3_cp0_wired_write(ti->ti_wired);
+
+	/*
+	 * If we are using register zero relative addressing to access cpu_info
+	 * in the exception vectors, enter that mapping into TLB now.
+	 */
+	if (ci->ci_tlb_slot >= 0) {
+		const uint32_t tlb_lo = MIPS3_PG_G|MIPS3_PG_V
+		    | mips3_paddr_to_tlbpfn((vaddr_t)ci);
+
+		tlb_enter(ci->ci_tlb_slot, -PAGE_SIZE, tlb_lo);
+	}
+
+	/*
+	 * Flush the icache just be sure.
+	 */
+	mips_icache_sync_all();
+
+	/*
+	 * Announce we are hatched
+	 */
+	atomic_or_ulong(&cpus_hatched, cpu_mask);
+
+	/*
+	 * Now wait to be set free!
+	 */
+	while ((cpus_running & cpu_mask) == 0) {
+		/* spin, spin, spin */
+	}
+
+	/*
+	 * Now turn on interrupts.
+	 */
+	spl0();
+
+	/*
+	 * And do a tail call to idle_loop
+	 */
+	idle_loop(NULL);
+}
+
+void
 cpu_boot_secondary_processors(void)
 {
-	if (pmap_tlb0_info.ti_wired != MIPS3_TLB_WIRED_UPAGES)
-		mips3_cp0_wired_write(pmap_tlb0_info.ti_wired);
+	for (struct cpu_info *ci = cpu_info_store.ci_next;
+	     ci != NULL;
+	     ci = ci->ci_next) {
+		const u_long cpu_mask = 1L << cpu_index(ci);
+		KASSERT(!CPU_IS_PRIMARY(ci));
+		KASSERT(ci->ci_data.cpu_idlelwp);
+
+		/*
+		 * Skip this CPU if it didn't sucessfully hatch.
+		 */
+		if ((cpus_hatched & cpu_mask) == 0)
+			continue;
 
-	(*mips_locoresw.lsw_boot_secondary_processors)();
+		atomic_or_ulong(&ci->ci_flags, CPUF_RUNNING);
+		atomic_or_ulong(&cpus_running, cpu_mask);
+	}
 }
 #endif /* MULTIPROCESSOR */
 

Index: src/sys/arch/mips/mips/genassym.cf
diff -u src/sys/arch/mips/mips/genassym.cf:1.44.12.20 src/sys/arch/mips/mips/genassym.cf:1.44.12.21
--- src/sys/arch/mips/mips/genassym.cf:1.44.12.20	Sun Feb 28 23:45:06 2010
+++ src/sys/arch/mips/mips/genassym.cf	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.44.12.20 2010/02/28 23:45:06 matt Exp $
+#	$NetBSD: genassym.cf,v 1.44.12.21 2010/03/01 19:29:41 matt Exp $
 #
 # Copyright (c) 1992, 1993
 #	The Regents of the University of California.  All rights reserved.
@@ -284,6 +284,7 @@
 define	CPU_INFO_CPL		offsetof(struct cpu_info, ci_cpl)
 define	CPU_INFO_IDEPTH		offsetof(struct cpu_info, ci_idepth)
 define	CPU_INFO_CURLWP		offsetof(struct cpu_info, ci_curlwp)
+define	CPU_INFO_IDLELWP	offsetof(struct cpu_info, ci_data.cpu_idlelwp)
 ifndef NOFPU
 define	CPU_INFO_FPCURLWP	offsetof(struct cpu_info, ci_fpcurlwp)
 endif

Index: src/sys/arch/mips/mips/locore_mips3.S
diff -u src/sys/arch/mips/mips/locore_mips3.S:1.93.38.7 src/sys/arch/mips/mips/locore_mips3.S:1.93.38.8
--- src/sys/arch/mips/mips/locore_mips3.S:1.93.38.7	Thu Feb 25 05:45:12 2010
+++ src/sys/arch/mips/mips/locore_mips3.S	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore_mips3.S,v 1.93.38.7 2010/02/25 05:45:12 matt Exp $	*/
+/*	$NetBSD: locore_mips3.S,v 1.93.38.8 2010/03/01 19:29:41 matt Exp $	*/
 
 /*
  * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
@@ -83,6 +83,7 @@
 #include "opt_cputype.h"
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
+#include "opt_multiprocessor.h"
 #include "opt_kgdb.h"
 
 #include <sys/cdefs.h>
@@ -572,3 +573,51 @@
 	j	ra
 	 nop
 END(mips3_cp0_tlb_page_mask_probe)
+
+#ifdef MULTIPROCESSOR
+/*
+ * The presence of this routine here will causes MIPS1 MULTIPROCESSOR kernels
+ * to fail, as they should since we won't support much abominations.
+ *
+ * MD code calls/jumps to with the pointer to this CPU's cpu_info in a1,
+ * sp set to ci->ci_data.cpu_idlwp->l_md.md_utf.  gp will be overridden so
+ * 0 can be supplied if needed.  (This happens to match what CFE wants)
+ */
+NESTED_NOPROFILE(cpu_trampoline, 0, ra)
+	/*
+	 * We act as the idle lwp so make it CURLWP.  When know
+	 * that the cpu_info is a KSEG0 address.
+	 */
+	move	a0, a1
+	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
+	nop
+	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
+
+#ifdef _LP64
+	li	v0, MIPS_SR_KX			# allow 64bit addressing
+#else
+	li	v0, 0
+#endif
+	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
+	COP0_SYNC
+
+	/*
+	 * Indicate that no one has called us.
+	 */
+	move	ra, zero
+	REG_S	ra, CALLFRAME_RA(sp)
+
+#ifdef __GP_SUPPORT__
+	/*
+	 * New execution constant needs GP to be loaded.
+	 */
+	PTR_LA	gp, _C_LABEL(_gp)
+#endif
+
+	/*
+	 * and off we go.
+	 */
+	j	_C_LABEL(cpu_hatch)		# does everything
+	 nop
+END(cpu_trampoline)
+#endif /* MULTIPROCESSOR */

Index: src/sys/arch/mips/mips/mipsX_subr.S
diff -u src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.29 src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.30
--- src/sys/arch/mips/mips/mipsX_subr.S:1.26.36.1.2.29	Sun Feb 28 03:28:54 2010
+++ src/sys/arch/mips/mips/mipsX_subr.S	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: mipsX_subr.S,v 1.26.36.1.2.29 2010/02/28 03:28:54 matt Exp $	*/
+/*	$NetBSD: mipsX_subr.S,v 1.26.36.1.2.30 2010/03/01 19:29:41 matt Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -2708,8 +2708,8 @@
 	PTR_WORD _C_LABEL(MIPSX(lwp_trampoline))
 	PTR_WORD _C_LABEL(nullop)	# cpu_idle
 	PTR_WORD _C_LABEL(MIPSX(setfunc_trampoline))
-	PTR_WORD _C_LABEL(nullop)	# boot secondary processors
 	PTR_WORD _C_LABEL(nullop)	# send ipi
+	PTR_WORD _C_LABEL(nullop)	# cpu_offline_md
 	PTR_WORD _C_LABEL(nullop)	# spare
 	PTR_WORD _C_LABEL(nullop)	# spare
 

Index: src/sys/arch/mips/mips/mips_machdep.c
diff -u src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.39 src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.40
--- src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.39	Sun Feb 28 23:45:06 2010
+++ src/sys/arch/mips/mips/mips_machdep.c	Mon Mar  1 19:29:41 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.39 2010/02/28 23:45:06 matt Exp $	*/
+/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.40 2010/03/01 19:29:41 matt Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -112,7 +112,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.39 2010/02/28 23:45:06 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.40 2010/03/01 19:29:41 matt Exp $");
 
 #define	__INTR_PRIVATE
 
@@ -175,11 +175,6 @@
 u_long	cpu_dump_mempagecnt(void);
 int	cpu_dump(void);
 
-#ifndef NOFPU
-kmutex_t fp_lock __aligned(32);
-kcondvar_t fp_cv __aligned(32);
-#endif
-
 #if defined(MIPS3_PLUS)
 uint32_t mips3_cp0_tlb_page_mask_probe(void);
 uint64_t mips3_cp0_tlb_entry_hi_probe(void);
@@ -229,22 +224,6 @@
 	.mips_fpu_id = 0xffffffff,
 };
 
-struct cpu_info cpu_info_store
-#ifdef MULTIPROCESSOR
-	__section(".data1")
-	__aligned(1LU << ilog2((2*sizeof(struct cpu_info)-1)))
-#endif
-    = {
-	.ci_curlwp = &lwp0,
-#ifndef NOFPU
-	.ci_fpcurlwp = &lwp0,
-#endif
-	.ci_tlb_info = &pmap_tlb0_info,
-	.ci_pmap_segbase = (void *)(MIPS_KSEG2_START + 0x1eadbeef),
-	.ci_cpl = IPL_HIGH,
-	.ci_tlb_slot = -1,
-};
-
 struct	user *proc0paddr;
 
 void *	msgbufaddr;

Reply via email to