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