Module Name:    src
Committed By:   macallan
Date:           Fri Jan 29 01:54:14 UTC 2016

Modified Files:
        src/sys/arch/evbmips/conf: CI20 files.ingenic
        src/sys/arch/evbmips/ingenic: clock.c intr.c machdep.c mainbus.c
Added Files:
        src/sys/arch/evbmips/ingenic: cpu.c cpu_startup.S

Log Message:
first shot at SMP support, very much broken and experimental
So far the 2nd core wakes up, makes its way to the idle loop, and things lock
up when we start the timer interrupt.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/evbmips/conf/CI20
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/evbmips/conf/files.ingenic
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/evbmips/ingenic/clock.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbmips/ingenic/cpu.c \
    src/sys/arch/evbmips/ingenic/cpu_startup.S
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbmips/ingenic/intr.c \
    src/sys/arch/evbmips/ingenic/machdep.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbmips/ingenic/mainbus.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/evbmips/conf/CI20
diff -u src/sys/arch/evbmips/conf/CI20:1.20 src/sys/arch/evbmips/conf/CI20:1.21
--- src/sys/arch/evbmips/conf/CI20:1.20	Sun Jan  3 06:23:25 2016
+++ src/sys/arch/evbmips/conf/CI20	Fri Jan 29 01:54:13 2016
@@ -1,4 +1,4 @@
-#	$NetBSD: CI20,v 1.20 2016/01/03 06:23:25 macallan Exp $
+#	$NetBSD: CI20,v 1.21 2016/01/29 01:54:13 macallan Exp $
 #
 # MIPS Creator CI20
 #
@@ -7,7 +7,7 @@ include 	"arch/evbmips/conf/std.ingenic"
 
 #options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"CI20-$Revision: 1.20 $"
+#ident 		"CI20-$Revision: 1.21 $"
 
 maxusers	32
 
@@ -138,7 +138,7 @@ config		netbsd	root on sd0a type ffs
 mainbus0 	at root
 #options 	MULTIPROCESSOR
 
-cpu0 		at mainbus?
+cpu* 		at mainbus?
 #wdog0		at mainbus?
 apbus0		at mainbus?
 

Index: src/sys/arch/evbmips/conf/files.ingenic
diff -u src/sys/arch/evbmips/conf/files.ingenic:1.5 src/sys/arch/evbmips/conf/files.ingenic:1.6
--- src/sys/arch/evbmips/conf/files.ingenic:1.5	Fri Dec 26 17:45:27 2014
+++ src/sys/arch/evbmips/conf/files.ingenic	Fri Jan 29 01:54:13 2016
@@ -1,4 +1,4 @@
-#	$NetBSD: files.ingenic,v 1.5 2014/12/26 17:45:27 macallan Exp $
+#	$NetBSD: files.ingenic,v 1.6 2016/01/29 01:54:13 macallan Exp $
 
 
 file	arch/mips/mips/bus_dma.c
@@ -12,6 +12,7 @@ file	arch/evbmips/ingenic/autoconf.c
 file	arch/evbmips/ingenic/machdep.c
 file	arch/evbmips/ingenic/intr.c
 file	arch/evbmips/ingenic/clock.c
+file	arch/evbmips/ingenic/cpu_startup.S
 
 # System bus
 device	mainbus { }
@@ -20,7 +21,7 @@ file	arch/evbmips/ingenic/mainbus.c		mai
 
 device	cpu
 attach	cpu at mainbus
-file	arch/evbmips/evbmips/cpu.c		cpu
+file	arch/evbmips/ingenic/cpu.c		cpu
 
 # Memory Disk
 file	dev/md_root.c				memory_disk_hooks

Index: src/sys/arch/evbmips/ingenic/clock.c
diff -u src/sys/arch/evbmips/ingenic/clock.c:1.6 src/sys/arch/evbmips/ingenic/clock.c:1.7
--- src/sys/arch/evbmips/ingenic/clock.c:1.6	Tue Jun 30 04:10:10 2015
+++ src/sys/arch/evbmips/ingenic/clock.c	Fri Jan 29 01:54:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: clock.c,v 1.6 2015/06/30 04:10:10 macallan Exp $ */
+/*	$NetBSD: clock.c,v 1.7 2016/01/29 01:54:14 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -27,7 +27,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.6 2015/06/30 04:10:10 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.7 2016/01/29 01:54:14 macallan Exp $");
+
+#include "opt_multiprocessor.h"
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -130,6 +132,8 @@ cpu_initclocks(void)
 	
 	printf("INTC %08x %08x\n", readreg(JZ_ICSR0), readreg(JZ_ICSR1));
 	delay(3000000);
+	printf("%s %d\n", __func__, MFC0(12, 3));
+	printf("%s %08x\n", __func__, MFC0(12, 4));
 #endif
 }
 
@@ -190,6 +194,7 @@ void
 ingenic_clockintr(uint32_t id)
 {
 	extern struct clockframe cf;
+	int s = splsched();
 	struct cpu_info * const ci = curcpu();
 #ifdef USE_OST
 	uint32_t new_cnt;
@@ -198,7 +203,6 @@ ingenic_clockintr(uint32_t id)
 	/* clear flags */
 	writereg(JZ_TC_TFCR, TFR_OSTFLAG);
 
-	KASSERT((ci->ci_cycles_per_hz & ~(0xffffffff)) == 0);
 	ci->ci_next_cp0_clk_intr += (uint32_t)(ci->ci_cycles_per_hz & 0xffffffff);
 #ifdef USE_OST
 	writereg(JZ_OST_DATA, ci->ci_next_cp0_clk_intr);
@@ -228,5 +232,13 @@ ingenic_clockintr(uint32_t id)
 		ingenic_puts("+");
 	}
 #endif
+#ifdef MULTIPROCESSOR
+	/*
+	 * XXX
+	 * needs to take the IPI lock and ping all online CPUs, not just core 1
+	 */
+	MTC0(1 << IPI_CLOCK, 20, 1);
+#endif
 	hardclock(&cf);
+	splx(s);
 }

Index: src/sys/arch/evbmips/ingenic/intr.c
diff -u src/sys/arch/evbmips/ingenic/intr.c:1.9 src/sys/arch/evbmips/ingenic/intr.c:1.10
--- src/sys/arch/evbmips/ingenic/intr.c:1.9	Sat Apr  4 13:06:01 2015
+++ src/sys/arch/evbmips/ingenic/intr.c	Fri Jan 29 01:54:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.c,v 1.9 2015/04/04 13:06:01 macallan Exp $ */
+/*	$NetBSD: intr.c,v 1.10 2016/01/29 01:54:14 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -27,10 +27,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.9 2015/04/04 13:06:01 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.10 2016/01/29 01:54:14 macallan Exp $");
 
 #define __INTR_PRIVATE
 
+#include "opt_multiprocessor.h"
+
 #include <sys/param.h>
 #include <sys/cpu.h>
 #include <sys/device.h>
@@ -46,9 +48,15 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.9
 
 #include "opt_ingenic.h"
 
+#ifdef INGENIC_INTR_DEBUG
+#define DPRINTF printf
+#else
+#define DPRINTF while (0) printf
+#endif
+
 extern void ingenic_clockintr(uint32_t);
 extern void ingenic_puts(const char *);
-
+extern struct clockframe cf;
 /*
  * This is a mask of bits to clear in the SR when we go to a
  * given hardware interrupt priority level.
@@ -122,7 +130,12 @@ evbmips_intr_init(void)
 	reg = MFC0(12, 4);	/* reset entry and interrupts */
 	reg &= 0xffff0000;
 	reg |= REIM_IRQ0_M | REIM_MIRQ0_M;
+#ifdef MULTIPROCESSOR
+	reg |= REIM_MIRQ1_M;
+#endif
 	MTC0(reg, 12, 4);
+	MTC0(0, 20, 1);	/* ping the 2nd core */
+	DPRINTF("%s %08x\n", __func__, reg);
 }
 
 void
@@ -143,7 +156,7 @@ evbmips_iointr(int ipl, vaddr_t pc, uint
 
 	/*
 	 * XXX
-	 * the manual counts the softint bits as INT0 and INT1, out headers
+	 * the manual counts the softint bits as INT0 and INT1, our headers
 	 * don't so everything here looks off by two
 	 */
 	if (ipending & MIPS_INT_MASK_1) {
@@ -151,6 +164,7 @@ evbmips_iointr(int ipl, vaddr_t pc, uint
 		 * this is a mailbox interrupt / IPI
 		 */
 		uint32_t reg;
+		int s = splsched();
 
 		/* read pending IPIs */
 		reg = MFC0(12, 3);
@@ -176,7 +190,10 @@ evbmips_iointr(int ipl, vaddr_t pc, uint
 #ifdef MULTIPROCESSOR
 				uint32_t tag;
 				tag = MFC0(CP0_CORE_MBOX, 1);
-				ipi_process(curcpu(), tag);
+				ingenic_puts("1");
+				if (tag & 0x400)
+					hardclock(&cf);
+				//ipi_process(curcpu(), tag);
 #ifdef INGENIC_INTR_DEBUG
 				snprintf(buffer, 256,
 				    "IPI for core 1, msg %08x\n", tag);
@@ -188,6 +205,7 @@ evbmips_iointr(int ipl, vaddr_t pc, uint
 				MTC0(reg, 12, 3);
 			}
 		}
+		splx(s);
 	}
 	if (ipending & MIPS_INT_MASK_2) {
 		/* this is a timer interrupt */
@@ -211,9 +229,9 @@ evbmips_iointr(int ipl, vaddr_t pc, uint
 		 */
 		mask = readreg(JZ_ICPR0);
 		if (mask & 0x0c000000) {
-			writereg(JZ_ICMSR0, mask);
+			writereg(JZ_ICMSR0, 0x0c000000);
 			ingenic_clockintr(id);
-			writereg(JZ_ICMCR0, mask);
+			writereg(JZ_ICMCR0, 0x0c000000);
 			clockintrs.ev_count++;
 		}
 		ingenic_irq(ipl);
Index: src/sys/arch/evbmips/ingenic/machdep.c
diff -u src/sys/arch/evbmips/ingenic/machdep.c:1.9 src/sys/arch/evbmips/ingenic/machdep.c:1.10
--- src/sys/arch/evbmips/ingenic/machdep.c:1.9	Sat Jul 11 19:00:04 2015
+++ src/sys/arch/evbmips/ingenic/machdep.c	Fri Jan 29 01:54:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.9 2015/07/11 19:00:04 macallan Exp $ */
+/*	$NetBSD: machdep.c,v 1.10 2016/01/29 01:54:14 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.9 2015/07/11 19:00:04 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.10 2016/01/29 01:54:14 macallan Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 
 #include <sys/reboot.h>
 #include <sys/cpu.h>
 #include <sys/bus.h>
+#include <sys/mutex.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -79,6 +80,10 @@ void	ingenic_putchar_init(void);
 void	ingenic_puts(const char *);
 void	ingenic_com_cnattach(void);
 
+#ifdef MULTIPROCESSOR
+kmutex_t ingenic_ipi_lock;
+#endif
+
 static void
 cal_timer(void)
 {
@@ -123,12 +128,12 @@ ingenic_cpu_init(struct cpu_info *ci)
 
 	/* enable IPIs for this core */
 	reg = MFC0(12, 4);	/* reset entry and interrupts */
-	reg &= 0xffff0000;
 	if (cpu_index(ci) == 1) {
 		reg |= REIM_MIRQ1_M;
 	} else
 		reg |= REIM_MIRQ0_M;
 	MTC0(reg, 12, 4);
+	printf("%s %d %08x\n", __func__, cpu_index(ci), reg);
 }
 
 static int
@@ -138,6 +143,7 @@ ingenic_send_ipi(struct cpu_info *ci, in
 
 	msg = 1 << tag;
 
+	mutex_enter(&ingenic_ipi_lock);
 	if (kcpuset_isset(cpus_running, cpu_index(ci))) {
 		if (cpu_index(ci) == 0) {
 			MTC0(msg, CP0_CORE_MBOX, 0);
@@ -145,9 +151,10 @@ ingenic_send_ipi(struct cpu_info *ci, in
 			MTC0(msg, CP0_CORE_MBOX, 1);
 		}
 	}
+	mutex_exit(&ingenic_ipi_lock);
 	return 0;
 }
-#endif
+#endif /* MULTIPROCESSOR */
 
 void
 mach_init(void)
@@ -221,6 +228,7 @@ mach_init(void)
 	mips_init_lwp0_uarea();
 
 #ifdef MULTIPROCESSOR
+	mutex_init(&ingenic_ipi_lock, MUTEX_DEFAULT, IPL_HIGH);
 	mips_locoresw.lsw_send_ipi = ingenic_send_ipi;
 	mips_locoresw.lsw_cpu_init = ingenic_cpu_init;
 #endif

Index: src/sys/arch/evbmips/ingenic/mainbus.c
diff -u src/sys/arch/evbmips/ingenic/mainbus.c:1.4 src/sys/arch/evbmips/ingenic/mainbus.c:1.5
--- src/sys/arch/evbmips/ingenic/mainbus.c:1.4	Sat Apr  4 13:06:01 2015
+++ src/sys/arch/evbmips/ingenic/mainbus.c	Fri Jan 29 01:54:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mainbus.c,v 1.4 2015/04/04 13:06:01 macallan Exp $ */
+/*	$NetBSD: mainbus.c,v 1.5 2016/01/29 01:54:14 macallan Exp $ */
 
 /*-
  * Copyright (c) 2014 Michael Lorenz
@@ -27,7 +27,9 @@
  */
  
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.4 2015/04/04 13:06:01 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.5 2016/01/29 01:54:14 macallan Exp $");
+
+#include "opt_multiprocessor.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -58,7 +60,9 @@ struct mainbusdev {
 
 struct mainbusdev mainbusdevs[] = {
 	{ "cpu",	},
-	{ "com",	},
+#ifdef MULTIPROCESSOR
+	{ "cpu",	},
+#endif
 	{ "apbus",	},
 	{ NULL,		}
 };

Added files:

Index: src/sys/arch/evbmips/ingenic/cpu.c
diff -u /dev/null src/sys/arch/evbmips/ingenic/cpu.c:1.1
--- /dev/null	Fri Jan 29 01:54:14 2016
+++ src/sys/arch/evbmips/ingenic/cpu.c	Fri Jan 29 01:54:14 2016
@@ -0,0 +1,122 @@
+/*	$NetBSD: cpu.c,v 1.1 2016/01/29 01:54:14 macallan Exp $	*/
+
+/*
+ * Copyright 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Simon Burge for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.1 2016/01/29 01:54:14 macallan Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/cpu.h>
+
+#include <mips/locore.h>
+#include <mips/asm.h>
+#include <mips/ingenic/ingenic_regs.h>
+
+#include "opt_ingenic.h"
+
+static int	cpu_match(device_t, cfdata_t, void *);
+static void	cpu_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(cpu, 0,
+    cpu_match, cpu_attach, NULL, NULL);
+
+struct cpu_info *startup_cpu_info;
+extern void *ingenic_wakeup;
+
+static int
+cpu_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct mainbusdev {
+		const char *md_name;
+	} *aa = aux;
+	if (strcmp(aa->md_name, "cpu") == 0) return 1;
+	return 0;
+}
+
+static void
+cpu_attach(device_t parent, device_t self, void *aux)
+{
+	struct cpu_info *ci = curcpu();
+	int unit;
+
+	if ((unit = device_unit(self)) > 0) {
+#ifdef MULTIPROCESSOR
+		uint32_t vec, reg;
+		int bail = 10000;
+		
+		startup_cpu_info = cpu_info_alloc(NULL, unit, 0, unit, 0);
+		startup_cpu_info->ci_cpu_freq = ci->ci_cpu_freq;
+		ci = startup_cpu_info;
+		wbflush();
+		vec = (uint32_t)&ingenic_wakeup;
+		reg = MFC0(12, 4);	/* reset entry reg */
+		reg &= ~REIM_ENTRY_M;
+		reg |= vec;
+		MTC0(reg, 12, 4);
+		reg = MFC0(12, 2);	/* core control reg */
+		reg |= CC_RPC1;		/* use our exception vector */
+		reg &= ~CC_SW_RST1;	/* get core 1 out of reset */
+		MTC0(reg, 12, 2);
+		while ((!kcpuset_isset(cpus_hatched, cpu_index(startup_cpu_info))) && (bail > 0)) {
+			delay(1000);
+			bail--;
+		}
+		if (!kcpuset_isset(cpus_hatched, cpu_index(startup_cpu_info))) {
+			aprint_error_dev(self, "did not hatch\n");
+			return;
+		}
+#else
+		aprint_normal_dev(self,
+		    "processor off-line; "
+		    "multiprocessor support not present in kernel\n");
+		return;
+#endif
+
+	}
+	ci->ci_dev = self;
+	self->dv_private = ci;
+
+	aprint_normal(": %lu.%02luMHz (hz cycles = %lu, delay divisor = %lu)\n",
+	    ci->ci_cpu_freq / 1000000,
+	    (ci->ci_cpu_freq % 1000000) / 10000,
+	    ci->ci_cycles_per_hz, ci->ci_divisor_delay);
+
+	aprint_normal_dev(self, "");
+	cpu_identify(self);
+	cpu_attach_common(self, ci);
+}
Index: src/sys/arch/evbmips/ingenic/cpu_startup.S
diff -u /dev/null src/sys/arch/evbmips/ingenic/cpu_startup.S:1.1
--- /dev/null	Fri Jan 29 01:54:14 2016
+++ src/sys/arch/evbmips/ingenic/cpu_startup.S	Fri Jan 29 01:54:14 2016
@@ -0,0 +1,130 @@
+/*	$NetBSD: cpu_startup.S,v 1.1 2016/01/29 01:54:14 macallan Exp $ */
+
+/*-
+ * Copyright (c) 2015 Michael Lorenz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_cputype.h"
+#include "opt_multiprocessor.h"
+
+#include <sys/cdefs.h>
+#include <sys/endian.h>
+
+#include <mips/asm.h>
+RCSID("$NetBSD: cpu_startup.S,v 1.1 2016/01/29 01:54:14 macallan Exp $");
+
+#ifdef MULTIPROCESSOR
+
+#include <mips/cpuregs.h>
+#include <mips/cache_r4k.h>
+
+#include "assym.h"
+
+#define CACHE_SIZE (32 * 1024)
+#define CACHE_LINESIZE 32
+
+NESTED_NOPROFILE(ingenic_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
+	// Loop until idlelwp is filled in.
+1:	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
+	nop
+	beqz	MIPS_CURLWP, 1b
+	 nop
+	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
+
+	li	v0, 0
+	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
+	COP0_SYNC
+
+	PTR_L	sp, L_MD_UTF(MIPS_CURLWP)	# fetch KSP
+
+	/*
+	 * Indicate that no one has called us.
+	 */
+	move	ra, zero
+	REG_S	ra, CALLFRAME_RA(sp)
+
+	/*
+	 * New execution constant needs GP to be loaded.
+	 */
+	PTR_LA	gp, _C_LABEL(_gp)
+
+	/*
+	 * and off we go.
+	 */
+	j	_C_LABEL(cpu_hatch)		# does everything
+	 nop
+END(ingenic_trampoline)
+
+
+/*
+ * exception vector secondary CPUs take when started
+ */
+.p2align 16
+VECTOR(ingenic_wakeup, unknown)
+	.set	noat
+
+	mtc0	zero, MIPS_COP_0_CAUSE
+	COP0_SYNC
+
+	/* init caches */
+	li	t0, MIPS_KSEG0_START
+	ori	t1, t0, CACHE_SIZE
+	mtc0	zero, MIPS_COP_0_TAG_LO, 0
+	COP0_SYNC
+1:	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_I, 0(t0)
+	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_D, 0(t0)
+	addiu	t0, t0, CACHE_LINESIZE
+	bne	t0, t1, 1b
+	 nop
+
+	/* kseg0 cache attribute */
+	mfc0	t0, MIPS_COP_0_CONFIG, 0
+	ori	t0, t0, MIPS3_TLB_ATTR_WB_NONCOHERENT
+	mtc0	t0, MIPS_COP_0_CONFIG, 0
+	COP0_SYNC
+
+	/* pagemask */
+	mtc0	zero, MIPS_COP_0_TLB_PG_MASK, 0
+	COP0_SYNC
+
+	/*
+	 * - set a1 to corresponding cpu_info
+	 * - set sp to ci->ci_data.cpu_idlelwp->l_md.md_utf
+	 * - jump to cpu_trampoline
+	 */
+	PTR_L	a1, _C_LABEL(startup_cpu_info)
+	nop
+
+	j	ingenic_trampoline
+	  nop
+	.set	at
+VECTOR_END(ingenic_wakeup)
+
+#endif /* MULTIPROCESSOR */

Reply via email to