Module Name:    src
Committed By:   cliff
Date:           Sun Jan 24 05:39:57 UTC 2010

Modified Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_cpu.c rmixl_subr.S

Log Message:
- cpu_rmixl_attach calls cpu_setup_trampoline to get control of
  subordinate CPUs from firmware by using the 'wakeup' callback method
  and into cpu_wakeup_trampoline where they just spin pending further work.
- the callback requires re-basing the stack pointer to be in KSEG0,
  done in asm subroutine rmixlfw_wakeup_cpu


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/arch/mips/rmi/rmixl_cpu.c \
    src/sys/arch/mips/rmi/rmixl_subr.S

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/rmi/rmixl_cpu.c
diff -u src/sys/arch/mips/rmi/rmixl_cpu.c:1.1.2.2 src/sys/arch/mips/rmi/rmixl_cpu.c:1.1.2.3
--- src/sys/arch/mips/rmi/rmixl_cpu.c:1.1.2.2	Wed Jan 20 20:48:12 2010
+++ src/sys/arch/mips/rmi/rmixl_cpu.c	Sun Jan 24 05:39:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_cpu.c,v 1.1.2.2 2010/01/20 20:48:12 matt Exp $	*/
+/*	$NetBSD: rmixl_cpu.c,v 1.1.2.3 2010/01/24 05:39:57 cliff Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -38,18 +38,27 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_cpu.c,v 1.1.2.2 2010/01/20 20:48:12 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_cpu.c,v 1.1.2.3 2010/01/24 05:39:57 cliff Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
 #include <sys/cpu.h>
+#include <sys/lock.h>
+#include <uvm/uvm_pglist.h>
+#include <uvm/uvm_extern.h>
+#include <mips/rmi/rmixlreg.h>
 #include <mips/rmi/rmixlvar.h>
 #include <mips/rmi/rmixl_cpucorevar.h>
 
 static int	cpu_rmixl_match(device_t, cfdata_t, void *);
 static void	cpu_rmixl_attach(device_t, device_t, void *);
 
+#ifdef MULTIPROCESSOR
+void		cpu_trampoline_park(void);
+static void	cpu_setup_trampoline(struct device *, struct cpu_info *);
+#endif
+
 CFATTACH_DECL_NEW(cpu_rmixl, 0, cpu_rmixl_match, cpu_rmixl_attach, NULL, NULL);
 
 static int
@@ -75,6 +84,7 @@
 cpu_rmixl_attach(device_t parent, device_t self, void *aux)
 {
 	struct cpucore_attach_args *ca = aux;
+
 	if (ca->ca_thread == 0 && ca->ca_core == 0) {
 		struct cpu_info * const ci = curcpu();
 		ci->ci_dev = self;
@@ -82,6 +92,7 @@
 #ifdef MULTIPROCESSOR
 	} else {
 		struct pglist pglist;
+		int error;
 
 		/*
 		 * Grab a page from the first 256MB to use to store
@@ -98,12 +109,115 @@
 		const paddr_t pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&pglist));
 		const vaddr_t va = MIPS_PHYS_TO_KSEG0(pa);
 		struct cpu_info * const ci = (void *) (va + 0x400);
-		memset(va, 0, PAGE_SIZE);
+		memset((void *)va, 0, PAGE_SIZE);
 		ci->ci_ebase = va;
 		ci->ci_ebase_pa = pa;
 		ci->ci_dev = self;
+		KASSERT(ca->ca_core < 8);
+		KASSERT(ca->ca_thread < 4);
+		ci->ci_cpuid = (ca->ca_core << 2) | ca->ca_thread;
 		self->dv_private = ci;
+
+		cpu_setup_trampoline(self, ci);
+
 #endif
 	}
 	aprint_normal("\n");
 }
+
+#ifdef MULTIPROCESSOR
+void
+cpu_trampoline_park(void)
+{
+}
+
+#if 0
+static void
+cpu_setup_trampoline(struct device *self, struct cpu_info *ci)
+{
+	volatile struct rmixlfw_cpu_wakeup_info *wip;
+	u_int cpu, core, thread;
+	uint32_t ipi;
+	int32_t addr;
+	uint64_t gp;
+	uint64_t sp;
+	uint32_t mask;
+	volatile uint32_t *maskp;
+	__cpu_simple_lock_t *llk;
+	volatile uint32_t *xflag;			/* ??? */
+	extern void cpu_wakeup_trampoline(void);
+
+	cpu = ci->ci_cpuid;
+	core = cpu >> 2;
+	thread = cpu & __BITS(1,0);
+printf("\n%s: cpu %d, core %d, thread %d\n", __func__, cpu, core, thread);
+
+	wip = &rmixl_configuration.rc_cpu_wakeup_info[cpu];
+printf("%s: wip %p\n", __func__, wip);
+
+	llk = (__cpu_simple_lock_t *)(intptr_t)wip->loader_lock;
+printf("%s: llk %p\n", __func__, llk);
+
+	/* XXX WTF */
+	xflag = (volatile uint32_t *)(intptr_t)(wip->loader_lock + 0x2c);
+printf("%s: xflag %p, %#x\n", __func__, xflag, *xflag);
+
+	ipi = (thread << RMIXL_PIC_IPIBASE_ID_THREAD_SHIFT)
+	    | (core << RMIXL_PIC_IPIBASE_ID_CORE_SHIFT)
+	    | RMIXLFW_IPI_WAKEUP;
+printf("%s: ipi %#x\n", __func__, ipi);
+
+	/* entry addr must be uncached, use KSEG1 */
+	addr = (int32_t)MIPS_PHYS_TO_KSEG1(
+			MIPS_KSEG0_TO_PHYS(cpu_wakeup_trampoline));
+printf("%s: addr %#x\n", __func__, addr);
+
+	__asm__ volatile("move	%0, $gp\n" : "=r"(gp));
+printf("%s: gp %#"PRIx64"\n", __func__, gp);
+
+	sp = (256 * 1024) - 32;			/* XXX TMP FIXME */
+	sp = MIPS_PHYS_TO_KSEG1(sp);
+printf("%s: sp %#"PRIx64"\n", __func__, sp);
+
+	maskp = (uint32_t *)(intptr_t)wip->global_wakeup_mask;
+printf("%s: maskp %p\n", __func__, maskp);
+
+	__cpu_simple_lock(llk);
+
+	wip->entry.addr = addr;
+	wip->entry.args = 0;
+if (0) {
+	wip->entry.sp = sp;
+	wip->entry.gp = gp;
+}
+
+	mask = *maskp;
+	mask |= 1 << cpu;
+	*maskp = mask;
+
+#if 0
+	*xflag = mask;	/* XXX */
+#endif
+
+	RMIXL_IOREG_WRITE(RMIXL_PIC_IPIBASE, ipi);
+
+	__cpu_simple_unlock(llk);
+
+	Debugger();
+}
+#else
+static uint64_t argv[4] = { 0x1234,  0x2345, 0x3456, 0x4567 };
+static void
+cpu_setup_trampoline(struct device *self, struct cpu_info *ci)
+{
+	void (*wakeup_cpu)(void *, void *, unsigned int);
+	extern void cpu_wakeup_trampoline(void);
+	extern void rmixlfw_wakeup_cpu(void *, void *, u_int64_t, void *);
+
+	wakeup_cpu = (void *)rmixl_configuration.rc_psb_info.wakeup;
+
+	rmixlfw_wakeup_cpu(cpu_wakeup_trampoline, argv,
+		1 << ci->ci_cpuid, wakeup_cpu);
+}
+#endif	/* 0 */
+#endif	/* MULTIPROCESSOR */
Index: src/sys/arch/mips/rmi/rmixl_subr.S
diff -u src/sys/arch/mips/rmi/rmixl_subr.S:1.1.2.2 src/sys/arch/mips/rmi/rmixl_subr.S:1.1.2.3
--- src/sys/arch/mips/rmi/rmixl_subr.S:1.1.2.2	Thu Dec 31 00:53:00 2009
+++ src/sys/arch/mips/rmi/rmixl_subr.S	Sun Jan 24 05:39:57 2010
@@ -1,11 +1,13 @@
-/*	$NetBSD: rmixl_subr.S,v 1.1.2.2 2009/12/31 00:53:00 matt Exp $	*/
+/*	$NetBSD: rmixl_subr.S,v 1.1.2.3 2010/01/24 05:39:57 cliff Exp $	*/
 
 #include "opt_cputype.h"
 
 #include <sys/cdefs.h>
 
-#include <mips/asm.h>
 #include <mips/cpuregs.h>
+#include <mips/asm.h>
+
+#include "assym.h"
 
 	.set	push
         .set    noreorder
@@ -38,4 +40,33 @@
 	mtcr	a1, a0
 END(rmixl_mtcr)
 
+/*
+ * rmixlfw_wakeup_cpu(func, args, mask, callback)
+ */
+NESTED(rmixlfw_wakeup_cpu, CALLFRAME_SIZ, ra)
+	PTR_ADDU	sp, sp, -CALLFRAME_SIZ
+	REG_S		ra, CALLFRAME_RA(sp)
+	REG_S		s0, CALLFRAME_S0(sp)
+
+	move		s0, sp			/* save sp */
+	srl		t0, sp, 0		/* nuke upper half */
+	li		t1, MIPS_KSEG0_START
+	jalr		a3			/* callback to firmware */
+	 or		sp, t0, t1		/* delay slot */
+	move		sp, s0			/* restore sp */
+
+	REG_L		s0, CALLFRAME_S0(sp)
+	REG_L		ra, CALLFRAME_RA(sp)
+	jr		ra
+	 PTR_ADDU	sp, sp, CALLFRAME_SIZ	/* delay slot */
+END(rmixlfw_wakeup_cpu)
+
+/*
+ * cpu_wakeup_trampoline
+ */
+NESTED(cpu_wakeup_trampoline, CALLFRAME_SIZ, ra)
+	j	.
+	nop
+END(cpu_wakeup_trampoline)
+
 	.set	pop

Reply via email to