Module Name:    src
Committed By:   snj
Date:           Wed Mar 11 20:22:56 UTC 2015

Modified Files:
        src/distrib/utils/embedded/conf [netbsd-7]: rpi.conf
        src/etc/etc.evbarm [netbsd-7]: Makefile.inc
        src/sys/arch/arm/broadcom [netbsd-7]: bcm2835_intr.c bcm2835_obio.c
            bcm2835_space.c bcm2835reg.h bcm2835var.h files.bcm2835
        src/sys/arch/arm/cortex [netbsd-7]: a9_mpsubr.S armperiph.c gtmr.c
            gtmr_var.h mpcore_var.h
        src/sys/arch/arm/include [netbsd-7]: cpu.h
        src/sys/arch/evbarm/conf [netbsd-7]: RPI mk.rpi std.rpi
        src/sys/arch/evbarm/rpi [netbsd-7]: genassym.cf rpi.h rpi_machdep.c
            rpi_start.S
Added Files:
        src/sys/arch/evbarm/conf [netbsd-7]: RPI2 RPI2_INSTALL
        src/sys/arch/evbarm/rpi [netbsd-7]: rpi2_start.S

Log Message:
Pull up following revision(s) (requested by skrll in ticket #582):
        distrib/utils/embedded/conf/rpi.conf: revision 1.27
        etc/etc.evbarm/Makefile.inc: revision 1.70
        sys/arch/arm/broadcom/bcm2835_intr.c: revision 1.5-1.7
        sys/arch/arm/broadcom/bcm2835_obio.c: revision 1.23, 1.24
        sys/arch/arm/broadcom/bcm2835_space.c: revision 1.8
        sys/arch/arm/broadcom/bcm2835reg.h: revision 1.14
        sys/arch/arm/broadcom/bcm2835var.h: revision 1.2
        sys/arch/arm/broadcom/files.bcm2835: revision 1.24
        sys/arch/arm/cortex/a9_mpsubr.S: revision 1.30
        sys/arch/arm/cortex/armperiph.c: revision 1.8, 1.9
        sys/arch/arm/cortex/gtmr.c: revision 1.9
        sys/arch/arm/cortex/gtmr_var.h: revision 1.5
        sys/arch/arm/cortex/mpcore_var.h: revision 1.3
        sys/arch/arm/include/cpu.h: revision 1.84
        sys/arch/evbarm/conf/RPI2: revision 1.1, 1.2
        sys/arch/evbarm/conf/RPI2_INSTALL: revision 1.1
        sys/arch/evbarm/conf/RPI: revision 1.59, 1.60
        sys/arch/evbarm/conf/mk.rpi: revision 1.4
        sys/arch/evbarm/conf/std.rpi: revisions 1.16-1.19 via patch
        sys/arch/evbarm/rpi/genassym.cf: revision 1.2
        sys/arch/evbarm/rpi/rpi.h: revision 1.4
        sys/arch/evbarm/rpi/rpi2_start.S: revision 1.1
        sys/arch/evbarm/rpi/rpi_machdep.c: revision 1.57, 1.58 via patch
        sys/arch/evbarm/rpi/rpi_start.S: revision 1.13
Move some options into std.rpi
--
Add __HAVE_MM_MD_CACHE_ALIASING
Pull up following revision(s) (requested by skrll in ticket #582):
Fix TPIDRPRW_IS_CURLWP builds.
--
A MULTIPROCESSOR kernel requires TPIDRPRW_IS_CURCPU.
--
Use TPIDRPRW_IS_CURLWP as it's a slight code reduction and performance
improvement.
Initial RPI2 support - it doesn't work yet. The generic timer gets messed
up somehow.
This commit changes the KVA layout of the RPI.
--
Make this compile where gtmr isn't used.
--
Spin up the non-boot CPUs, but don't allow cpu_boot_secondary_processors
to see them for now.
RPI2 nows works well with only the boot cpu.
--
Appease a KASSERT - will be remove when MULTIPROCESSOR RPI2 is fixed.
--
Add RPI2 to kernels build for both earmv[67].
Use the earmv6 built kernels to create an image that can be used on both
RPI and RPI2
--
Add an RPI2_INSTALL


To generate a diff of this commit:
cvs rdiff -u -r1.24.4.2 -r1.24.4.3 src/distrib/utils/embedded/conf/rpi.conf
cvs rdiff -u -r1.63.2.2 -r1.63.2.3 src/etc/etc.evbarm/Makefile.inc
cvs rdiff -u -r1.3.12.1 -r1.3.12.2 src/sys/arch/arm/broadcom/bcm2835_intr.c
cvs rdiff -u -r1.20.2.1 -r1.20.2.2 src/sys/arch/arm/broadcom/bcm2835_obio.c
cvs rdiff -u -r1.6 -r1.6.10.1 src/sys/arch/arm/broadcom/bcm2835_space.c
cvs rdiff -u -r1.10.12.2 -r1.10.12.3 src/sys/arch/arm/broadcom/bcm2835reg.h
cvs rdiff -u -r1.1 -r1.1.18.1 src/sys/arch/arm/broadcom/bcm2835var.h
cvs rdiff -u -r1.21.2.2 -r1.21.2.3 src/sys/arch/arm/broadcom/files.bcm2835
cvs rdiff -u -r1.18.2.1 -r1.18.2.2 src/sys/arch/arm/cortex/a9_mpsubr.S
cvs rdiff -u -r1.4 -r1.4.10.1 src/sys/arch/arm/cortex/armperiph.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/sys/arch/arm/cortex/gtmr.c
cvs rdiff -u -r1.4 -r1.4.6.1 src/sys/arch/arm/cortex/gtmr_var.h
cvs rdiff -u -r1.2 -r1.2.10.1 src/sys/arch/arm/cortex/mpcore_var.h
cvs rdiff -u -r1.83 -r1.83.4.1 src/sys/arch/arm/include/cpu.h
cvs rdiff -u -r1.46.2.5 -r1.46.2.6 src/sys/arch/evbarm/conf/RPI
cvs rdiff -u -r0 -r1.2.2.2 src/sys/arch/evbarm/conf/RPI2
cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/evbarm/conf/RPI2_INSTALL
cvs rdiff -u -r1.3 -r1.3.12.1 src/sys/arch/evbarm/conf/mk.rpi
cvs rdiff -u -r1.14 -r1.14.2.1 src/sys/arch/evbarm/conf/std.rpi
cvs rdiff -u -r1.1 -r1.1.18.1 src/sys/arch/evbarm/rpi/genassym.cf
cvs rdiff -u -r1.3 -r1.3.2.1 src/sys/arch/evbarm/rpi/rpi.h
cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/evbarm/rpi/rpi2_start.S
cvs rdiff -u -r1.43.2.3 -r1.43.2.4 src/sys/arch/evbarm/rpi/rpi_machdep.c
cvs rdiff -u -r1.12 -r1.12.2.1 src/sys/arch/evbarm/rpi/rpi_start.S

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

Modified files:

Index: src/distrib/utils/embedded/conf/rpi.conf
diff -u src/distrib/utils/embedded/conf/rpi.conf:1.24.4.2 src/distrib/utils/embedded/conf/rpi.conf:1.24.4.3
--- src/distrib/utils/embedded/conf/rpi.conf:1.24.4.2	Sat Feb 14 07:20:48 2015
+++ src/distrib/utils/embedded/conf/rpi.conf	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-# $NetBSD: rpi.conf,v 1.24.4.2 2015/02/14 07:20:48 snj Exp $
+# $NetBSD: rpi.conf,v 1.24.4.3 2015/03/11 20:22:55 snj Exp $
 # Raspberry Pi customization script used by mkimage
 #
 
@@ -48,6 +48,8 @@ EOF
 }
 
 populate() {
+	rpi2_kernel="$(echo $kernel | sed 's/RPI/RPI2/g')"
+
 	cat > ${mnt}/boot/cmdline.txt << EOF
 root=ld0a console=fb
 #fb=1280x1024		# to select a mode, otherwise try EDID 
@@ -58,7 +60,7 @@ EOF
 		exit 1
 	fi
 
-	echo "${bar} installing kernel ${bar}"
+	echo "${bar} installing RPI kernel ${bar}"
 	case ${kernel} in
 	*.gz)
 		gzip -dc ${kernel} > ${mnt}/boot/kernel.img
@@ -68,6 +70,16 @@ EOF
 		;;
 	esac
 
+	echo "${bar} installing RPI2 kernel ${bar}"
+	case ${rpi2_kernel} in
+	*.gz)
+		gzip -dc ${rpi2_kernel} > ${mnt}/boot/kernel7.img
+		;;
+	*)
+		cp ${rpi_kernel} ${mnt}/boot/kernel7.img
+		;;
+	esac
+
 	echo "${bar} installing firmware files ${bar}"
 	(cd ${mnt}/boot &&
 		for f in ${firmwarefiles}; do

Index: src/etc/etc.evbarm/Makefile.inc
diff -u src/etc/etc.evbarm/Makefile.inc:1.63.2.2 src/etc/etc.evbarm/Makefile.inc:1.63.2.3
--- src/etc/etc.evbarm/Makefile.inc:1.63.2.2	Fri Nov 14 10:04:40 2014
+++ src/etc/etc.evbarm/Makefile.inc	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.inc,v 1.63.2.2 2014/11/14 10:04:40 martin Exp $
+#	$NetBSD: Makefile.inc,v 1.63.2.3 2015/03/11 20:22:55 snj Exp $
 #
 #	etc.evbarm/Makefile.inc -- evbarm-specific etc Makefile targets
 #
@@ -69,6 +69,8 @@ EVBARM_BOARDS.armv5t+=		SHEEVAPLUG
 #EVBARM_BOARDS.armv6hf+= 	IMX31LITE
 EVBARM_BOARDS.armv6+=		RPI
 EVBARM_BOARDS.armv6hf+=	 	RPI
+KERNEL_SETS.armv6+=		RPI2
+KERNEL_SETS.armv6hf+=	 	RPI2
 EVBARM_BOARDS.armv6+=		TISDP2420
 EVBARM_BOARDS.armv6hf+= 	TISDP2420
 #EVBARM_BOARDS.armv6+=		TISDP2430
@@ -103,6 +105,8 @@ EVBARM_BOARDS.armv7hf+=		OMAP5EVM
 #EVBARM_BOARDS.armv7+=		OVERO
 EVBARM_BOARDS.armv7+=		PANDABOARD
 EVBARM_BOARDS.armv7hf+= 	PANDABOARD
+EVBARM_BOARDS.armv7+=		RPI2
+EVBARM_BOARDS.armv7hf+=	 	RPI2
 EVBARM_BOARDS.armv7+=		KOBO
 EVBARM_BOARDS.armv7hf+= 	KOBO
 .endif
@@ -161,6 +165,7 @@ SNAP_MD_POST_DEPS+=	smp_beagleboard
 
 .if !empty(KERNEL_SETS:MRPI)
 smp_rpi: ${IMAGE.kern}/netbsd-RPI.bin.gz __mkimage
+#            XXX ${IMAGE.kern}/netbsd-RPI2.bin.gz
 .if empty(ALL_KERNELS) || !empty(ALL_KERNELS:MRPI)
 SNAP_MD_POST_DEPS+=	smp_rpi
 .endif

Index: src/sys/arch/arm/broadcom/bcm2835_intr.c
diff -u src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.1 src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.2
--- src/sys/arch/arm/broadcom/bcm2835_intr.c:1.3.12.1	Thu Sep 11 14:20:11 2014
+++ src/sys/arch/arm/broadcom/bcm2835_intr.c	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835_intr.c,v 1.3.12.1 2014/09/11 14:20:11 martin Exp $	*/
+/*	$NetBSD: bcm2835_intr.c,v 1.3.12.2 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,21 +30,28 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.3.12.1 2014/09/11 14:20:11 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.3.12.2 2015/03/11 20:22:55 snj Exp $");
 
 #define _INTR_PRIVATE
 
+#include "opt_bcm283x.h"
+
 #include <sys/param.h>
-#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
 #include <sys/device.h>
+#include <sys/proc.h>
 
 #include <machine/intr.h>
-#include <sys/bus.h>
+
+#include <arm/locore.h>
 
 #include <arm/pic/picvar.h>
+#include <arm/cortex/gtmr_var.h>
 
 #include <arm/broadcom/bcm_amba.h>
 #include <arm/broadcom/bcm2835reg.h>
+#include <arm/broadcom/bcm2835var.h>
 
 static void bcm2835_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
 static void bcm2835_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
@@ -53,6 +60,29 @@ static void bcm2835_pic_establish_irq(st
 static void bcm2835_pic_source_name(struct pic_softc *, int, char *,
     size_t);
 
+#if defined(BCM2836)
+static void bcm2836mp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
+static void bcm2836mp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
+static int bcm2836mp_pic_find_pending_irqs(struct pic_softc *);
+static void bcm2836mp_pic_establish_irq(struct pic_softc *, struct intrsource *);
+static void bcm2836mp_pic_source_name(struct pic_softc *, int, char *,
+    size_t);
+#if 0
+#ifdef MULTIPROCESSOR
+int bcm2836mp_ipi_handler(void *);
+static void bcm2836mp_cpu_init(struct pic_softc *, struct cpu_info *);
+static void bcm2836mp_send_ipi(struct pic_softc *, const kcpuset_t *, u_long);
+#endif
+#endif
+#endif
+
+#ifdef MULTIPROCESSOR
+static void
+bcm2835_dummy(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi)
+{
+}
+#endif
+
 static int  bcm2835_icu_match(device_t, cfdata_t, void *);
 static void bcm2835_icu_attach(device_t, device_t, void *);
 
@@ -62,6 +92,9 @@ static struct pic_ops bcm2835_picops = {
 	.pic_find_pending_irqs = bcm2835_pic_find_pending_irqs,
 	.pic_establish_irq = bcm2835_pic_establish_irq,
 	.pic_source_name = bcm2835_pic_source_name,
+#if defined(MULTIPROCESSOR)
+	.pic_ipi_send = bcm2835_dummy,
+#endif
 };
 
 struct pic_softc bcm2835_pic = {
@@ -70,6 +103,26 @@ struct pic_softc bcm2835_pic = {
 	.pic_name = "bcm2835 pic",
 };
 
+#if defined(BCM2836)
+static struct pic_ops bcm2836mp_picops = {
+	.pic_unblock_irqs = bcm2836mp_pic_unblock_irqs,
+	.pic_block_irqs = bcm2836mp_pic_block_irqs,
+	.pic_find_pending_irqs = bcm2836mp_pic_find_pending_irqs,
+	.pic_establish_irq = bcm2836mp_pic_establish_irq,
+	.pic_source_name = bcm2836mp_pic_source_name,
+#if 0 && defined(MULTIPROCESSOR)
+	.pic_cpu_init = bcm2836mp_cpu_init,
+	.pic_ipi_send = bcm2836mp_send_ipi,
+#endif
+};
+
+struct pic_softc bcm2836mp_pic = {
+	.pic_ops = &bcm2836mp_picops,
+	.pic_maxsources = BCM2836MP_NIRQ,
+	.pic_name = "bcm2836 mp pic",
+};
+#endif
+
 struct bcm2835icu_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_iot;
@@ -111,6 +164,15 @@ static const char * const bcm2835_source
 	"GPU0 Halted",	"GPU1 Halted",	"Illegal #1",	"Illegal #0"
 };
 
+#if defined(BCM2836)
+static const char * const bcm2836mp_sources[BCM2836MP_NIRQ] = {
+	"cntpsirq",	"cntpnsirq",	"cnthpirq",	"cntvirq",
+	"mailbox0",	"mailbox1",	"mailbox2",	"mailbox3",
+};
+#endif
+
+#define	BCM2836_INTBIT_GPUPENDING	__BIT(8)
+
 #define	BCM2835_INTBIT_PENDING1		__BIT(8)
 #define	BCM2835_INTBIT_PENDING2		__BIT(9)
 #define	BCM2835_INTBIT_ARM		__BITS(0,7)
@@ -148,7 +210,16 @@ bcm2835_icu_attach(device_t parent, devi
 	}
 
 	bcmicu_sc = sc;
+
 	pic_add(sc->sc_pic, 0);
+
+#if defined(BCM2836)
+#if 0 && defined(MULTIPROCESSOR)
+	aprint_normal(": Multiprocessor");
+#endif
+	pic_add(&bcm2836mp_pic, BCM2836_INT_LOCALBASE);
+#endif
+
 	aprint_normal("\n");
 }
 
@@ -164,6 +235,9 @@ bcm2835_irq_handler(void *frame)
 
 	bcm2835_barrier();
 	ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic);
+#if defined(BCM2836)
+	ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic);
+#endif
 
 	/*
 	 * Record the pending_ipls and deliver them if we can.
@@ -247,3 +321,122 @@ bcm2835_pic_source_name(struct pic_softc
 
 	strlcpy(buf, bcm2835_sources[irq], len);
 }
+
+
+#if defined(BCM2836)
+
+#define	BCM2836MP_TIMER_IRQS	__BITS(3,0)
+#define	BCM2836MP_MAILBOX_IRQS	__BITS(4,4)
+
+#define	BCM2836MP_ALL_IRQS	\
+     (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS)
+
+static void
+bcm2836mp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
+    uint32_t irq_mask)
+{
+	const int cpuid = 0;
+
+//printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask);
+
+	if (irq_mask & BCM2836MP_TIMER_IRQS) {
+		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
+		uint32_t val = bus_space_read_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
+		val |= mask;
+		bus_space_write_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
+		    val);
+		bus_space_barrier(al_iot, al_ioh,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE,
+		    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
+//printf("%s: val %08x\n", __func__, val);
+	} else if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
+		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
+		uint32_t val = bus_space_read_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
+		val |= mask;
+		bus_space_write_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
+		    val);
+		bus_space_barrier(al_iot, al_ioh,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_SIZE,
+		    BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
+	}
+
+	return;
+}
+
+static void
+bcm2836mp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
+    uint32_t irq_mask)
+{
+	const int cpuid = 0;
+
+//printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask);
+	if (irq_mask & BCM2836MP_TIMER_IRQS) {
+		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
+		uint32_t val = bus_space_read_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
+		val &= ~mask;
+		bus_space_write_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
+		    val);
+//printf("%s: val %08x\n", __func__, val);
+	} else if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
+		uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
+		uint32_t val = bus_space_read_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
+		val &= ~mask;
+		bus_space_write_4(al_iot, al_ioh,
+		    BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
+		    val);
+	}
+
+	bcm2835_barrier();
+	return;
+}
+
+
+static int
+bcm2836mp_pic_find_pending_irqs(struct pic_softc *pic)
+{
+	const int cpuid = 0;
+	uint32_t lpending;
+	int ipl = 0;
+
+	bcm2835_barrier();
+
+	lpending = bus_space_read_4(al_iot, al_ioh,
+	    BCM2836_LOCAL_INTC_IRQPENDINGN(cpuid));
+
+	lpending &= ~BCM2836_INTBIT_GPUPENDING;
+	if (lpending & BCM2836MP_ALL_IRQS) {
+		ipl |= pic_mark_pending_sources(pic, 0 /* BCM2836_INT_LOCALBASE */,
+		    lpending & BCM2836MP_ALL_IRQS);
+	}
+
+	return ipl;
+}
+
+static void
+bcm2836mp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
+{
+
+	/* Nothing really*/
+	KASSERT(is->is_irq >= 0);
+	KASSERT(is->is_irq < BCM2836MP_NIRQ);
+//	KASSERT(is->is_type == IST_LEVEL);
+
+
+}
+
+static void
+bcm2836mp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
+{
+	irq %= 32;
+	strlcpy(buf, bcm2836mp_sources[irq], len);
+}
+#endif

Index: src/sys/arch/arm/broadcom/bcm2835_obio.c
diff -u src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.1 src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.2
--- src/sys/arch/arm/broadcom/bcm2835_obio.c:1.20.2.1	Thu Sep 11 14:20:11 2014
+++ src/sys/arch/arm/broadcom/bcm2835_obio.c	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835_obio.c,v 1.20.2.1 2014/09/11 14:20:11 martin Exp $	*/
+/*	$NetBSD: bcm2835_obio.c,v 1.20.2.2 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012, 2014 The NetBSD Foundation, Inc.
@@ -30,11 +30,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.20.2.1 2014/09/11 14:20:11 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.20.2.2 2015/03/11 20:22:55 snj Exp $");
 
 #include "locators.h"
 #include "obio.h"
 
+#include "opt_bcm283x.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
@@ -42,8 +44,12 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_obio
 #include <sys/bus.h>
 
 #include <arm/broadcom/bcm2835reg.h>
+#include <arm/broadcom/bcm2835var.h>
 #include <arm/broadcom/bcm_amba.h>
 
+#include <arm/cortex/mpcore_var.h>
+#include <arm/cortex/gtmr_var.h>
+
 struct obio_softc {
 	device_t		sc_dev;
 	bus_dma_tag_t		sc_dmat;
@@ -76,6 +82,13 @@ static const struct ambadev_locators bcm
 		.ad_size = BCM2835_ARMICU_SIZE,
 		.ad_intr = -1,
 	},
+#if defined(BCM2836)
+	{
+		/* GTMR */
+		.ad_name = "armgtmr",
+		.ad_intr = BCM2836_INT_CNTVIRQ_CPUN(0),
+	},
+#endif
 	{
 		/* Mailbox */
 		.ad_name = "bcmmbox",
@@ -83,6 +96,7 @@ static const struct ambadev_locators bcm
 		.ad_size = BCM2835_ARMMBOX_SIZE,
 		.ad_intr = -1, /* BCM2835_INT_ARMMAILBOX */
 	},
+#if !defined(BCM2836)
 	{
 		/* System Timer */
 		.ad_name = "bcmtmr",
@@ -90,6 +104,7 @@ static const struct ambadev_locators bcm
 		.ad_size = BCM2835_STIMER_SIZE,
 		.ad_intr = BCM2835_INT_TIMER3,
 	},
+#endif
 	{
 		/* VCHIQ */
 		.ad_name = "bcmvchiq",
@@ -192,6 +207,9 @@ obio_match(device_t parent, cfdata_t mat
 	return 1;
 }
 
+bus_space_tag_t al_iot = &bcm2835_bs_tag;
+bus_space_handle_t al_ioh;
+
 static void
 obio_attach(device_t parent, device_t self, void *aux)
 {
@@ -209,7 +227,11 @@ obio_attach(device_t parent, device_t se
 	sc->sc_dmat = &bcm2835_bus_dma_tag;
 
 	sc->sc_dmarange[0].dr_sysbase = 0;
+#if defined(BCM2836)
+	sc->sc_dmarange[0].dr_busbase = BCM2835_BUSADDR_CACHE_DIRECT;
+#else
 	sc->sc_dmarange[0].dr_busbase = BCM2835_BUSADDR_CACHE_COHERENT;
+#endif
 	sc->sc_dmarange[0].dr_len = physmem * PAGE_SIZE;
 	bcm2835_bus_dma_tag._ranges = sc->sc_dmarange;
 	bcm2835_bus_dma_tag._nranges = __arraycount(sc->sc_dmarange);
@@ -220,9 +242,31 @@ obio_attach(device_t parent, device_t se
 	aaa.aaa_iot = &bcm2835_bs_tag;
 	aaa.aaa_dmat = sc->sc_dmat;
 
+#if defined(BCM2836)
+	if (bus_space_map(al_iot, BCM2836_ARM_LOCAL_BASE, BCM2836_ARM_LOCAL_SIZE,
+	    0, &al_ioh)) {
+		aprint_error(": unable to map local space\n");
+		return;
+	}
+
+	bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_CONTROL, 0);
+	bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_PRESCALER, 0x80000000);
+#endif
+
 	for (; ad->ad_name != NULL; ad++) {
 		aprint_debug("dev=%s[%u], addr=%lx:+%lx\n",
 		    ad->ad_name, ad->ad_instance, ad->ad_addr, ad->ad_size);
+		if (strcmp(ad->ad_name, "armgtmr") == 0) {
+			struct mpcore_attach_args mpcaa = {
+				.mpcaa_name = "armgtmr",
+				.mpcaa_irq = ad->ad_intr,
+			};
+
+
+			config_found(self, &mpcaa, NULL);
+			continue;
+		}
+
 		aaa.aaa_name = ad->ad_name;
 		aaa.aaa_addr = ad->ad_addr;
 		aaa.aaa_size = ad->ad_size;
@@ -265,3 +309,10 @@ obio_print(void *aux, const char *name)
 
 	return UNCONF;
 }
+
+#ifdef MULTIPROCESSOR
+void
+bcm2836_cpu_hatch(struct cpu_info *ci)
+{
+}
+#endif

Index: src/sys/arch/arm/broadcom/bcm2835_space.c
diff -u src/sys/arch/arm/broadcom/bcm2835_space.c:1.6 src/sys/arch/arm/broadcom/bcm2835_space.c:1.6.10.1
--- src/sys/arch/arm/broadcom/bcm2835_space.c:1.6	Sun Apr 14 15:11:52 2013
+++ src/sys/arch/arm/broadcom/bcm2835_space.c	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835_space.c,v 1.6 2013/04/14 15:11:52 skrll Exp $	*/
+/*	$NetBSD: bcm2835_space.c,v 1.6.10.1 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_space.c,v 1.6 2013/04/14 15:11:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_space.c,v 1.6.10.1 2015/03/11 20:22:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_spac
 
 #include <sys/bus.h>
 
+#include <arm/locore.h>
 #include <arm/broadcom/bcm2835reg.h>
 
 /* Prototypes for all the bus_space structure functions */
@@ -290,8 +291,12 @@ bcm2835_bs_map(void *t, bus_addr_t ba, b
 	const struct pmap_devmap *pd;
 	int pmap_flags;
 
-	pa = ba & ~BCM2835_BUSADDR_CACHE_MASK;
 
+#if defined(BCM2836)
+	pa = ba;
+#else
+	pa = ba & ~BCM2835_BUSADDR_CACHE_MASK;
+#endif
 	/* this does device addresses */
 	if ((pd = pmap_devmap_find_pa(pa, size)) != NULL) {
 		/* Device was statically mapped. */

Index: src/sys/arch/arm/broadcom/bcm2835reg.h
diff -u src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.2 src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.3
--- src/sys/arch/arm/broadcom/bcm2835reg.h:1.10.12.2	Fri Oct  3 18:53:56 2014
+++ src/sys/arch/arm/broadcom/bcm2835reg.h	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835reg.h,v 1.10.12.2 2014/10/03 18:53:56 martin Exp $	*/
+/*	$NetBSD: bcm2835reg.h,v 1.10.12.3 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -38,7 +38,13 @@
 #ifndef	_BCM2835REG_H_
 #define	_BCM2835REG_H_
 
+#include "opt_bcm283x.h"
+
+#ifdef BCM2836
+#define	BCM2835_PERIPHERALS_BASE	0x3f000000
+#else
 #define	BCM2835_PERIPHERALS_BASE	0x20000000
+#endif
 #define	BCM2835_PERIPHERALS_SIZE	0x01000000	/* 16MBytes */
 #define	BCM2835_PERIPHERALS_BASE_BUS	0x7e000000
 #define	BCM2835_PERIPHERALS_TO_BUS(a) \
@@ -78,7 +84,7 @@
 #define	BCM2835_DMA15_SIZE	0x100
 
 #define BCM2835_IOPHYSTOVIRT(a) \
-    ((0xf0000000 | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xf0000000))
+    ((0xf0000000 | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xff000000))
 
 #define	BCM2835_BUSADDR_CACHE_MASK	0xc0000000
 #define	BCM2835_BUSADDR_CACHE_COHERENT	0x40000000
@@ -155,8 +161,71 @@
 #define	BCM2835_INT_ILLEGALTYPE0	(BCM2835_INT_BASICBASE + 6)
 #define	BCM2835_INT_ILLEGALTYPE1	(BCM2835_INT_BASICBASE + 7)
 
-#define	BCM2835_NIRQ	64 + 8
+#define	BCM2836_NCPUS			4
+
+#define	BCM2836_INT_LOCALBASE		96
+
+#define	BCM2836_INT_CNTPSIRQ		0
+#define	BCM2836_INT_CNTPNSIRQ		1
+#define	BCM2836_INT_CNTHPIRQ		2
+#define	BCM2836_INT_CNTVIRQ		3
+#define	BCM2836_INT_MAILBOX0		4
+#define	BCM2836_INT_MAILBOX1		5
+#define	BCM2836_INT_MAILBOX2		6
+#define	BCM2836_INT_MAILBOX3		7
+#define	BCM2836_INT_GPU_FAST		8
+#define	BCM2836_INT_PMU_FAST		9
+#define	BCM2836_INT_ZERO		10
+#define	BCM2836_INT_TIMER		11
+#define	BCM2836_INT_NLOCAL		12
+
+#define	BCM2836_INT_CNTVIRQ_CPUN(n)	(BCM2836_INT_LOCALBASE + ((n) * 32) + BCM2836_INT_CNTVIRQ)
+#define	BCM2836_INT_MAILBOX0_CPUN(n)	(BCM2836_INT_LOCALBASE + ((n) * 32) + BCM2836_INT_MAILBOX0)
+
+#define	BCM2835_NIRQ			96
+#define	BCM2836MP_NIRQ			32
 
 #define	BCM2835_UART0_CLK	3000000
 
+#define	BCM2836_ARM_LOCAL_VBASE \
+	BCM2835_IOPHYSTOVIRT(BCM2836_ARM_LOCAL_BASE)
+#define	BCM2836_ARM_LOCAL_BASE		0x40000000
+#define	BCM2836_ARM_LOCAL_SIZE		0x00001000	/* 4KBytes */
+
+#define	BCM2836_LOCAL_CONTROL		0x000
+#define	BCM2836_LOCAL_PRESCALER		0x008
+#define	BCM2836_LOCAL_GPU_INT_ROUTING	0x00c
+#define	BCM2836_LOCAL_PM_ROUTING_SET	0x010
+#define	BCM2836_LOCAL_PM_ROUTING_CLR	0x014
+#define	BCM2836_LOCAL_TIMER_LS		0x01c
+#define	BCM2836_LOCAL_TIMER_MS		0x020
+#define	BCM2836_LOCAL_INT_ROUTING	0x024
+#define	BCM2836_LOCAL_AXI_COUNT		0x02c
+#define	BCM2836_LOCAL_AXI_IRQ		0x030
+#define	BCM2836_LOCAL_TIMER_CONTROL	0x034
+#define	BCM2836_LOCAL_TIMER_WRITE	0x038
+
+
+#define	BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE	0x40
+#define	BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE	0x50
+#define	BCM2836_LOCAL_INTC_IRQPENDING_BASE	0x60
+#define	BCM2836_LOCAL_INTC_FIQPENDING_BASE	0x70
+
+#define	BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE	0x10
+#define	BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_SIZE	0x10
+
+#define	BCM2836_LOCAL_TIMER_IRQ_CONTROLN(n)	(BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE + 4*(n))
+#define	BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(n)	(BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE + 4*(n))
+#define	BCM2836_LOCAL_INTC_IRQPENDINGN(n)	(BCM2836_LOCAL_INTC_IRQPENDING_BASE + 4*(n))
+#define	BCM2836_LOCAL_INTC_FIQPENDINGN(n)	(BCM2836_LOCAL_INTC_FIQPENDING_BASE + 4*(n))
+
+#define	BCM2836_LOCAL_MAILBOX0_SETN(n)		(0x80 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX1_SETN(n)		(0x84 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX2_SETN(n)		(0x88 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX3_SETN(n)		(0x8c + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX0_CLRN(n)		(0xc0 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX1_CLRN(n)		(0xc4 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX2_CLRN(n)		(0xc8 + 0x10 * (n))
+#define	BCM2836_LOCAL_MAILBOX3_CLRN(n)		(0xcc + 0x10 * (n))
+
 #endif /* _BCM2835REG_H_ */

Index: src/sys/arch/arm/broadcom/bcm2835var.h
diff -u src/sys/arch/arm/broadcom/bcm2835var.h:1.1 src/sys/arch/arm/broadcom/bcm2835var.h:1.1.18.1
--- src/sys/arch/arm/broadcom/bcm2835var.h:1.1	Thu Jul 26 06:21:57 2012
+++ src/sys/arch/arm/broadcom/bcm2835var.h	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm2835var.h,v 1.1 2012/07/26 06:21:57 skrll Exp $	*/
+/*	$NetBSD: bcm2835var.h,v 1.1.18.1 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -39,6 +39,11 @@ extern struct bus_space bcm2835_bs_tag;
 extern struct bus_space bcm2835_a4x_bs_tag;
 extern struct arm32_bus_dma_tag bcm2835_bus_dma_tag;
 
+extern bus_space_tag_t al_iot;
+extern bus_space_handle_t al_ioh;
+
 bus_dma_tag_t bcm2835_bus_dma_init(struct arm32_bus_dma_tag *);
 
+void bcm2836_cpu_hatch(struct cpu_info *);
+
 #endif	/* _ARM_BROADCOM_BCM2835_VAR_H_ */

Index: src/sys/arch/arm/broadcom/files.bcm2835
diff -u src/sys/arch/arm/broadcom/files.bcm2835:1.21.2.2 src/sys/arch/arm/broadcom/files.bcm2835:1.21.2.3
--- src/sys/arch/arm/broadcom/files.bcm2835:1.21.2.2	Fri Oct  3 18:53:56 2014
+++ src/sys/arch/arm/broadcom/files.bcm2835	Wed Mar 11 20:22:55 2015
@@ -1,8 +1,10 @@
-#	$NetBSD: files.bcm2835,v 1.21.2.2 2014/10/03 18:53:56 martin Exp $
+#	$NetBSD: files.bcm2835,v 1.21.2.3 2015/03/11 20:22:55 snj Exp $
 #
 # Configuration info for Broadcom BCM2835 ARM Peripherals
 #
 
+defflag	opt_bcm283x.h			BCM2836
+
 include "arch/arm/pic/files.pic"
 
 define bcmmboxbus { }
@@ -21,7 +23,12 @@ file	arch/arm/broadcom/bcm2835_obio.c	ob
 file	arch/arm/broadcom/bcm2835_space.c	obio
 file	arch/arm/arm/bus_space_a4x.S		obio
 
-# Interrupt Controller (BCM2835_ARMICU_BASE)
+# ARMv7 Generic Timer
+device	armgtmr
+attach	armgtmr at obio
+file	arch/arm/cortex/gtmr.c			armgtmr
+
+# Interrupt Controller (BCM2835_ARMICU_BASE) #, pic_splfuncs
 device	bcmicu: pic, pic_splfuncs
 attach	bcmicu at obio with bcmicu
 file	arch/arm/broadcom/bcm2835_intr.c	bcmicu
@@ -34,7 +41,7 @@ file	arch/arm/broadcom/bcm2835_mbox.c	bc
 # System Timer (BCM2835_TIMER_BASE)
 device	bcmtmr
 attach	bcmtmr at obio with bcmtmr_amba
-file	arch/arm/broadcom/bcm2835_tmr.c		bcmtmr
+file	arch/arm/broadcom/bcm2835_tmr.c		bcmtmr & !bcm2836
 
 # Power Management, Reset Controller, and Watchdog (BCM2835_PM_BASE)
 device	bcmpm: sysmon_wdog

Index: src/sys/arch/arm/cortex/a9_mpsubr.S
diff -u src/sys/arch/arm/cortex/a9_mpsubr.S:1.18.2.1 src/sys/arch/arm/cortex/a9_mpsubr.S:1.18.2.2
--- src/sys/arch/arm/cortex/a9_mpsubr.S:1.18.2.1	Sun Nov  9 16:05:25 2014
+++ src/sys/arch/arm/cortex/a9_mpsubr.S	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: a9_mpsubr.S,v 1.18.2.1 2014/11/09 16:05:25 martin Exp $	*/
+/*	$NetBSD: a9_mpsubr.S,v 1.18.2.2 2015/03/11 20:22:55 snj Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -506,6 +506,10 @@ cortex_mpfault:
 // Secondary processors come here after exiting the SKU ROM.
 // Switches to kernel's endian almost immediately.
 //
+
+	.global	cortex_mpstart
+	.type	cortex_mpstart,%object
+
 cortex_mpstart:
 #ifndef MULTIPROCESSOR
 	//

Index: src/sys/arch/arm/cortex/armperiph.c
diff -u src/sys/arch/arm/cortex/armperiph.c:1.4 src/sys/arch/arm/cortex/armperiph.c:1.4.10.1
--- src/sys/arch/arm/cortex/armperiph.c:1.4	Thu Jun 20 05:30:21 2013
+++ src/sys/arch/arm/cortex/armperiph.c	Wed Mar 11 20:22:55 2015
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: armperiph.c,v 1.4 2013/06/20 05:30:21 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: armperiph.c,v 1.4.10.1 2015/03/11 20:22:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -40,6 +40,7 @@ __KERNEL_RCSID(1, "$NetBSD: armperiph.c,
 
 #include <arm/mainbus/mainbus.h>
 #include <arm/cortex/mpcore_var.h>
+#include <arm/cortex/gtmr_intr.h>
 
 static int armperiph_match(device_t, cfdata_t, void *);
 static void armperiph_attach(device_t, device_t, void *);
@@ -198,6 +199,11 @@ armperiph_attach(device_t parent, device
 			.mpcaa_off1 = cfg->cfg_devices[i].pi_off1,
 			.mpcaa_off2 = cfg->cfg_devices[i].pi_off2,
 		};
+#if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15)
+		if (strcmp(mpcaa.mpcaa_name, "armgtmr") == 0) {
+			mpcaa.mpcaa_irq = IRQ_GTMR_PPI_VTIMER;
+		}
+#endif
 
 		config_found(self, &mpcaa, NULL);
 	}

Index: src/sys/arch/arm/cortex/gtmr.c
diff -u src/sys/arch/arm/cortex/gtmr.c:1.8 src/sys/arch/arm/cortex/gtmr.c:1.8.2.1
--- src/sys/arch/arm/cortex/gtmr.c:1.8	Wed Jun 11 05:50:46 2014
+++ src/sys/arch/arm/cortex/gtmr.c	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: gtmr.c,v 1.8 2014/06/11 05:50:46 matt Exp $	*/
+/*	$NetBSD: gtmr.c,v 1.8.2.1 2015/03/11 20:22:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.8 2014/06/11 05:50:46 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.8.2.1 2015/03/11 20:22:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -51,8 +51,6 @@ __KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.8
 static int gtmr_match(device_t, cfdata_t, void *);
 static void gtmr_attach(device_t, device_t, void *);
 
-static int gtmr_intr(void *);
-
 static u_int gtmr_get_timecount(struct timecounter *);
 
 static struct gtmr_softc gtmr_sc;
@@ -95,6 +93,7 @@ gtmr_match(device_t parent, cfdata_t cf,
 static void
 gtmr_attach(device_t parent, device_t self, void *aux)
 {
+	struct mpcore_attach_args * const mpcaa = aux;
         struct gtmr_softc *sc = &gtmr_sc;
 	prop_dictionary_t dict = device_properties(self);
 	char freqbuf[sizeof("X.XXX SHz")];
@@ -125,12 +124,12 @@ gtmr_attach(device_t parent, device_t se
 	evcnt_attach_dynamic(&sc->sc_ev_missing_ticks, EVCNT_TYPE_MISC, NULL,
 	    device_xname(self), "missing interrupts");
 
-	sc->sc_global_ih = intr_establish(IRQ_GTMR_PPI_VTIMER, IPL_CLOCK,
+	sc->sc_global_ih = intr_establish(mpcaa->mpcaa_irq, IPL_CLOCK,
 	    IST_EDGE | IST_MPSAFE, gtmr_intr, NULL);
 	if (sc->sc_global_ih == NULL)
 		panic("%s: unable to register timer interrupt", __func__);
 	aprint_normal_dev(self, "interrupting on irq %d\n",
-	    IRQ_GTMR_PPI_VTIMER);
+	    mpcaa->mpcaa_irq);
 
 	const uint32_t cnt_frq = armreg_cnt_frq_read();
 	if (cnt_frq == 0) {
@@ -269,7 +268,7 @@ gtmr_bootdelay(unsigned int ticks)
  *
  *	Handle the hardclock interrupt.
  */
-static int
+int
 gtmr_intr(void *arg)
 {
 	const uint64_t now = armreg_cntv_ct_read();

Index: src/sys/arch/arm/cortex/gtmr_var.h
diff -u src/sys/arch/arm/cortex/gtmr_var.h:1.4 src/sys/arch/arm/cortex/gtmr_var.h:1.4.6.1
--- src/sys/arch/arm/cortex/gtmr_var.h:1.4	Fri Mar 28 21:41:46 2014
+++ src/sys/arch/arm/cortex/gtmr_var.h	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: gtmr_var.h,v 1.4 2014/03/28 21:41:46 matt Exp $ */
+/* $NetBSD: gtmr_var.h,v 1.4.6.1 2015/03/11 20:22:55 snj Exp $ */
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -44,6 +44,7 @@ struct gtmr_softc {
 
 #ifdef _KERNEL
 struct cpu_info;
+int	gtmr_intr(void *);
 void	gtmr_init_cpu_clock(struct cpu_info *);
 void	gtmr_delay(unsigned int n);
 void	gtmr_bootdelay(unsigned int n);

Index: src/sys/arch/arm/cortex/mpcore_var.h
diff -u src/sys/arch/arm/cortex/mpcore_var.h:1.2 src/sys/arch/arm/cortex/mpcore_var.h:1.2.10.1
--- src/sys/arch/arm/cortex/mpcore_var.h:1.2	Thu Jun 20 05:30:21 2013
+++ src/sys/arch/arm/cortex/mpcore_var.h	Wed Mar 11 20:22:55 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: mpcore_var.h,v 1.2 2013/06/20 05:30:21 matt Exp $ */
+/* $NetBSD: mpcore_var.h,v 1.2.10.1 2015/03/11 20:22:55 snj Exp $ */
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -37,6 +37,7 @@ struct mpcore_attach_args {
 	bus_space_handle_t mpcaa_memh;
 	bus_size_t mpcaa_off1;
 	bus_size_t mpcaa_off2;
+	int mpcaa_irq;
 };
 
 #endif /* _ARM_CORTEX_MPCORE_VAR_H_ */

Index: src/sys/arch/arm/include/cpu.h
diff -u src/sys/arch/arm/include/cpu.h:1.83 src/sys/arch/arm/include/cpu.h:1.83.4.1
--- src/sys/arch/arm/include/cpu.h:1.83	Fri Mar 28 21:44:59 2014
+++ src/sys/arch/arm/include/cpu.h	Wed Mar 11 20:22:56 2015
@@ -179,6 +179,9 @@ struct cpu_info {
 extern struct cpu_info cpu_info_store;
 
 #if defined(TPIDRPRW_IS_CURLWP)
+#if defined(MULTIPROCESSOR)
+#error MULTIPROCESSOR requires TPIDRPRW_IS_CURCPU not TPIDRPRW_IS_CURLWP
+#else
 static inline struct lwp *
 _curlwp(void)
 {
@@ -191,12 +194,8 @@ _curlwp_set(struct lwp *l)
 	armreg_tpidrprw_write((uintptr_t)l);
 }
 
-#define	curlwp		(_curlwp())
-static inline struct cpu_info *
-curcpu(void)
-{
-	return curlwp->l_cpu;
-}
+#define	curcpu()	(&cpu_info_store)
+#endif
 #elif defined(TPIDRPRW_IS_CURCPU)
 static inline struct cpu_info *
 curcpu(void)
@@ -206,7 +205,7 @@ curcpu(void)
 #elif !defined(MULTIPROCESSOR)
 #define	curcpu()	(&cpu_info_store)
 #else
-#error MULTIPROCESSOR requires TPIDRPRW_IS_CURLWP or TPIDRPRW_IS_CURCPU
+#error MULTIPROCESSOR requires TPIDRPRW_IS_CURCPU
 #endif /* !TPIDRPRW_IS_CURCPU && !TPIDRPRW_IS_CURLWP */
 
 #ifndef curlwp

Index: src/sys/arch/evbarm/conf/RPI
diff -u src/sys/arch/evbarm/conf/RPI:1.46.2.5 src/sys/arch/evbarm/conf/RPI:1.46.2.6
--- src/sys/arch/evbarm/conf/RPI:1.46.2.5	Tue Nov 25 15:51:47 2014
+++ src/sys/arch/evbarm/conf/RPI	Wed Mar 11 20:22:56 2015
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: RPI,v 1.46.2.5 2014/11/25 15:51:47 martin Exp $
+#	$NetBSD: RPI,v 1.46.2.6 2015/03/11 20:22:56 snj Exp $
 #
 #	RPi -- Raspberry Pi
 #
@@ -18,9 +18,10 @@ options 	RTC_OFFSET=0	# hardware clock i
 # CPU options
 
 options 	CPU_ARM1176
-options 	BCM2835
 options 	PMAPCOUNTERS
-options 	FPU_VFP
+options 	TPIDRPRW_IS_CURLWP
+options 	__HAVE_MM_MD_CACHE_ALIASING
+makeoptions 	CPUFLAGS="-march=armv6z -mtune=arm1176jzf-s -mfpu=vfp"
 
 # Architecture options
 
@@ -166,8 +167,8 @@ config		netbsd		root on ? type ?
 # The main bus device
 mainbus0	at root
 
-# The cpu
-cpu0		at mainbus?
+# The CPU(s)
+cpu*		at mainbus?
 
 # OBIO
 obio0		at mainbus?

Index: src/sys/arch/evbarm/conf/mk.rpi
diff -u src/sys/arch/evbarm/conf/mk.rpi:1.3 src/sys/arch/evbarm/conf/mk.rpi:1.3.12.1
--- src/sys/arch/evbarm/conf/mk.rpi:1.3	Sat Feb  9 20:48:38 2013
+++ src/sys/arch/evbarm/conf/mk.rpi	Wed Mar 11 20:22:56 2015
@@ -1,6 +1,4 @@
-#	$NetBSD: mk.rpi,v 1.3 2013/02/09 20:48:38 christos Exp $
-
-CPPFLAGS+= -march=armv6z -mtune=arm1176jzf-s -mfpu=vfp
+#	$NetBSD: mk.rpi,v 1.3.12.1 2015/03/11 20:22:56 snj Exp $
 
 SYSTEM_FIRST_OBJ=	rpi_start.o
 SYSTEM_FIRST_SFILE=	${THISARM}/rpi/rpi_start.S
@@ -10,7 +8,7 @@ _OSRELEASE!=		${HOST_SH} $S/conf/osrelea
 GENASSYM_EXTRAS+=	${THISARM}/rpi/genassym.cf
 
 KERNEL_BASE_PHYS=0x00008000
-KERNEL_BASE_VIRT=0xc0008000
+KERNEL_BASE_VIRT=0x80008000
 
 SYSTEM_LD_TAIL_EXTRA+=; \
 	echo ${OBJCOPY} -S -O binary $@ [email protected]; \

Index: src/sys/arch/evbarm/conf/std.rpi
diff -u src/sys/arch/evbarm/conf/std.rpi:1.14 src/sys/arch/evbarm/conf/std.rpi:1.14.2.1
--- src/sys/arch/evbarm/conf/std.rpi:1.14	Sun Apr  6 12:43:18 2014
+++ src/sys/arch/evbarm/conf/std.rpi	Wed Mar 11 20:22:56 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: std.rpi,v 1.14 2014/04/06 12:43:18 skrll Exp $
+#	$NetBSD: std.rpi,v 1.14.2.1 2015/03/11 20:22:56 snj Exp $
 #
 # standard NetBSD/evbarm for Raspberry Pi options
 
@@ -9,18 +9,18 @@ include 	"arch/evbarm/conf/std.evbarm"
 include		"arch/evbarm/conf/files.rpi"
 
 options 	MODULAR
-options 	ARM11_COMPAT_MMU
+options 	MODULAR_DEFAULT_AUTOLOAD
+options 	FPU_VFP
 options 	__HAVE_CPU_COUNTER
 options 	__HAVE_FAST_SOFTINTS		# should be in types.h
 options 	__HAVE_CPU_UAREA_ALLOC_IDLELWP
 options 	__HAVE_MM_MD_DIRECT_MAPPED_PHYS
-options 	TPIDRPRW_IS_CURCPU
 options 	ARM_HAS_VBAR
-options 	KERNEL_BASE_EXT=0xc0000000
+options 	KERNEL_BASE_EXT=0x80000000
 
 options 	EVBARM_BOARDTYPE="rpi"
 makeoptions	BOARDMKFRAG="${THISARM}/conf/mk.rpi"
-makeoptions	LOADADDRESS="0xc0008000"
+makeoptions	LOADADDRESS="0x80008000"
 
 options 	ARM_INTR_IMPL="<arch/arm/broadcom/bcm2835_intr.h>"
 options 	ARM_GENERIC_TODR

Index: src/sys/arch/evbarm/rpi/genassym.cf
diff -u src/sys/arch/evbarm/rpi/genassym.cf:1.1 src/sys/arch/evbarm/rpi/genassym.cf:1.1.18.1
--- src/sys/arch/evbarm/rpi/genassym.cf:1.1	Thu Jul 26 06:21:57 2012
+++ src/sys/arch/evbarm/rpi/genassym.cf	Wed Mar 11 20:22:56 2015
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.1 2012/07/26 06:21:57 skrll Exp $
+# $NetBSD: genassym.cf,v 1.1.18.1 2015/03/11 20:22:56 snj Exp $
 
 #-
 # Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -34,3 +34,7 @@ include <evbarm/rpi/rpi.h>
 define	RPI_KERNEL_IO_VBASE	RPI_KERNEL_IO_VBASE
 define	RPI_KERNEL_IO_PBASE	RPI_KERNEL_IO_PBASE
 define	RPI_KERNEL_IO_VSIZE	RPI_KERNEL_IO_VSIZE
+
+define	RPI_KERNEL_LOCAL_VBASE	RPI_KERNEL_LOCAL_VBASE
+define	RPI_KERNEL_LOCAL_PBASE	RPI_KERNEL_LOCAL_PBASE
+define	RPI_KERNEL_LOCAL_VSIZE	RPI_KERNEL_LOCAL_VSIZE

Index: src/sys/arch/evbarm/rpi/rpi.h
diff -u src/sys/arch/evbarm/rpi/rpi.h:1.3 src/sys/arch/evbarm/rpi/rpi.h:1.3.2.1
--- src/sys/arch/evbarm/rpi/rpi.h:1.3	Sun Apr  6 12:43:19 2014
+++ src/sys/arch/evbarm/rpi/rpi.h	Wed Mar 11 20:22:56 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi.h,v 1.3 2014/04/06 12:43:19 skrll Exp $	*/
+/*	$NetBSD: rpi.h,v 1.3.2.1 2015/03/11 20:22:56 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -35,10 +35,13 @@
 #include <arm/broadcom/bcm2835reg.h>
 
 /*
- * Kernel VM space: KERNEL_VM_BASE to 0xf0000000
+ * Memory may be mapped VA:PA starting at 0x80000000:0x00000000
+ * RPI2 has 1GB upto 0xc0000000
+ *
+ * Kernel VM space: 800MB at KERNEL_VM_BASE
  */
-#define	KERNEL_VM_BASE		(KERNEL_BASE + 0x20000000)
-#define	KERNEL_VM_SIZE		(0xf0000000 - KERNEL_VM_BASE)
+#define	KERNEL_VM_BASE		0xc0000000
+#define	KERNEL_VM_SIZE		(BCM2835_PERIPHERALS_VBASE - KERNEL_VM_BASE)
 
 /*
  * BCM2835 ARM Peripherals
@@ -47,4 +50,13 @@
 #define	RPI_KERNEL_IO_PBASE		BCM2835_PERIPHERALS_BASE
 #define	RPI_KERNEL_IO_VSIZE		BCM2835_PERIPHERALS_SIZE
 
+/*
+ * BCM2836 Local control block
+ */
+#define	RPI_KERNEL_LOCAL_VBASE	BCM2836_ARM_LOCAL_VBASE
+#define	RPI_KERNEL_LOCAL_PBASE	BCM2836_ARM_LOCAL_BASE
+#define	RPI_KERNEL_LOCAL_VSIZE	BCM2836_ARM_LOCAL_SIZE
+
+#define	RPI_REF_FREQ		19200000
+
 #endif	/* _EVBARM_RPI_RPI_H */

Index: src/sys/arch/evbarm/rpi/rpi_machdep.c
diff -u src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.3 src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.4
--- src/sys/arch/evbarm/rpi/rpi_machdep.c:1.43.2.3	Wed Jan 21 11:37:04 2015
+++ src/sys/arch/evbarm/rpi/rpi_machdep.c	Wed Mar 11 20:22:56 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi_machdep.c,v 1.43.2.3 2015/01/21 11:37:04 martin Exp $	*/
+/*	$NetBSD: rpi_machdep.c,v 1.43.2.4 2015/03/11 20:22:56 snj Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,12 +30,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.43.2.3 2015/01/21 11:37:04 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.43.2.4 2015/03/11 20:22:56 snj Exp $");
 
-#include "opt_evbarm_boardtype.h"
+#include "opt_arm_debug.h"
+#include "opt_bcm283x.h"
+#include "opt_cpuoptions.h"
 #include "opt_ddb.h"
+#include "opt_evbarm_boardtype.h"
 #include "opt_kgdb.h"
-#include "opt_arm_debug.h"
 #include "opt_vcprop.h"
 
 #include "sdhc.h"
@@ -78,6 +80,8 @@ __KERNEL_RCSID(0, "$NetBSD: rpi_machdep.
 
 #include <evbarm/rpi/rpi.h>
 
+#include <arm/cortex/gtmr_var.h>
+
 #ifdef DDB
 #include <machine/db_machdep.h>
 #include <ddb/db_sym.h>
@@ -115,9 +119,9 @@ static void rpi_device_register(device_t
  * kernel address space.  *Not* for general use.
  */
 
-#define	KERN_VTOPDIFF	((vaddr_t)KERNEL_BASE_phys - (vaddr_t)KERNEL_BASE_virt)
-#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va + KERN_VTOPDIFF))
-#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa - KERN_VTOPDIFF))
+#define KERN_VTOPDIFF	KERNEL_BASE_VOFFSET
+#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va - KERN_VTOPDIFF))
+#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa + KERN_VTOPDIFF))
 
 #ifndef RPI_FB_WIDTH
 #define RPI_FB_WIDTH	1280
@@ -126,7 +130,15 @@ static void rpi_device_register(device_t
 #define RPI_FB_HEIGHT	720
 #endif
 
+#if 0
+#define	PLCONADDR BCM2835_UART0_BASE
+#endif
+
+#ifdef BCM2836
+#define	PLCONADDR 0x3f201000
+#else
 #define	PLCONADDR 0x20201000
+#endif
 
 #ifndef CONSDEVNAME
 #define CONSDEVNAME "plcom"
@@ -461,6 +473,59 @@ rpi_bootparams(void)
 #endif
 }
 
+
+static void
+rpi_bootstrap(void)
+{
+#if defined(BCM2836)
+	arm_cpu_max = 4;
+	extern int cortex_mmuinfo;
+	bus_space_tag_t iot = &bcm2835_bs_tag;
+	bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("%s: %d cpus present\n", __func__, arm_cpu_max);
+#endif
+
+	extern void cortex_mpstart(void);
+	cortex_mmuinfo = armreg_ttbr_read();
+
+	for (size_t i = 1; i < arm_cpu_max; i++) {
+		bus_space_write_4(iot, ioh,
+		    BCM2836_LOCAL_MAILBOX3_SETN(i),
+		    (uint32_t)cortex_mpstart);
+
+		int timeout = 20;
+		while (timeout-- > 0) {
+			uint32_t val;
+
+			val = bus_space_read_4(iot, ioh,
+			    BCM2836_LOCAL_MAILBOX3_CLRN(i));
+			if (val == 0)
+				break;
+		}
+	}
+
+	for (int loop = 0; loop < 16; loop++) {
+		if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
+			break;
+		gtmr_delay(10000);
+	}
+
+	for (size_t i = 1; i < arm_cpu_max; i++) {
+		if ((arm_cpu_hatched & (1 << i)) == 0) {
+			printf("%s: warning: cpu%zu failed to hatch\n",
+			    __func__, i);
+		}
+	}
+
+	/*
+	 * XXXNH: Disable non-boot CPUs for now
+	 */
+	arm_cpu_hatched = 0;
+#endif
+}
+
 /*
  * Static device mappings. These peripheral registers are mapped at
  * fixed virtual addresses very early in initarm() so that we can use
@@ -481,12 +546,21 @@ rpi_bootparams(void)
 
 static const struct pmap_devmap rpi_devmap[] = {
 	{
-		_A(RPI_KERNEL_IO_VBASE),	/* 0xf2000000 */
-		_A(RPI_KERNEL_IO_PBASE),	/* 0x20000000 */
+		_A(RPI_KERNEL_IO_VBASE),
+		_A(RPI_KERNEL_IO_PBASE),
 		_S(RPI_KERNEL_IO_VSIZE),	/* 16Mb */
 		VM_PROT_READ|VM_PROT_WRITE,
 		PTE_NOCACHE,
 	},
+#if defined(BCM2836)
+	{
+		_A(RPI_KERNEL_LOCAL_VBASE),
+		_A(RPI_KERNEL_LOCAL_PBASE),
+		_S(RPI_KERNEL_LOCAL_VSIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_NOCACHE,
+	},
+#endif
 	{ 0, 0, 0, 0, 0 }
 };
 
@@ -528,8 +602,14 @@ initarm(void *arg)
 #define _BDSTR(s)	#s
 	printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
 
+#ifdef CORTEX_PMC
+	cortex_pmc_ccnt_init();
+#endif
+
 	rpi_bootparams();
 
+	rpi_bootstrap();
+
 	if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) {
 		curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate;
 #ifdef VERBOSE_INIT_ARM
@@ -823,6 +903,17 @@ rpi_device_register(device_t dev, void *
 {
 	prop_dictionary_t dict = device_properties(dev);
 
+#if defined(BCM2836)
+	if (device_is_a(dev, "armgtmr")) {
+		/*
+		 * The frequency of the generic timer is the reference
+		 * frequency.
+		 */
+		prop_dictionary_set_uint32(dict, "frequency", RPI_REF_FREQ);
+		return;
+	}
+#endif
+
 	if (device_is_a(dev, "bcmdmac") &&
 	    vcprop_tag_success_p(&vb.vbt_dmachan.tag)) {
 		prop_dictionary_set_uint32(dict,

Index: src/sys/arch/evbarm/rpi/rpi_start.S
diff -u src/sys/arch/evbarm/rpi/rpi_start.S:1.12 src/sys/arch/evbarm/rpi/rpi_start.S:1.12.2.1
--- src/sys/arch/evbarm/rpi/rpi_start.S:1.12	Sun Jul 27 09:04:09 2014
+++ src/sys/arch/evbarm/rpi/rpi_start.S	Wed Mar 11 20:22:56 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: rpi_start.S,v 1.12 2014/07/27 09:04:09 skrll Exp $	*/
+/*	$NetBSD: rpi_start.S,v 1.12.2.1 2015/03/11 20:22:56 snj Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
@@ -81,6 +81,12 @@
  * SUCH DAMAGE.
  */
 
+#include "opt_bcm283x.h"
+
+#if defined(BCM2836)
+#include <evbarm/rpi/rpi2_start.S>
+#else
+
 #include "opt_cputypes.h"
 #include "opt_cpuoptions.h"
 
@@ -88,7 +94,7 @@
 #include <arm/armreg.h>
 #include "assym.h"
 
-RCSID("$NetBSD: rpi_start.S,v 1.12 2014/07/27 09:04:09 skrll Exp $")
+RCSID("$NetBSD: rpi_start.S,v 1.12.2.1 2015/03/11 20:22:56 snj Exp $")
 
 /*
  * Workaround Erratum 411920
@@ -347,6 +353,8 @@ mmu_init_table:
 
 	/* end of table */
 	MMU_INIT(0, 0, 0, 0)
+#endif
+
 
 	.globl	_C_LABEL(rpi_boot_regs)
 rpi_boot_regs:

Added files:

Index: src/sys/arch/evbarm/conf/RPI2
diff -u /dev/null src/sys/arch/evbarm/conf/RPI2:1.2.2.2
--- /dev/null	Wed Mar 11 20:22:56 2015
+++ src/sys/arch/evbarm/conf/RPI2	Wed Mar 11 20:22:56 2015
@@ -0,0 +1,24 @@
+#
+#	$NetBSD: RPI2,v 1.2.2.2 2015/03/11 20:22:56 snj Exp $
+#
+#	RPi2 -- Raspberry Pi 2
+#
+
+include "arch/evbarm/conf/RPI"
+
+no options 	CPU_ARM1176
+no options 	TPIDRPRW_IS_CURLWP
+no options 	__HAVE_MM_MD_CACHE_ALIASING
+no makeoptions	CPUFLAGS
+
+options 	BCM2836
+options 	CPU_CORTEXA7
+options 	MULTIPROCESSOR
+options 	CORTEX_PMC
+options 	TPIDRPRW_IS_CURCPU
+makeoptions 	CPUFLAGS="-mcpu=cortex-a7 -mfpu=neon"
+
+# Architecture options
+
+no bcmtmr0	at obio?		# System Timer
+armgtmr0	at obio?		# ARM Generic Timer

Index: src/sys/arch/evbarm/conf/RPI2_INSTALL
diff -u /dev/null src/sys/arch/evbarm/conf/RPI2_INSTALL:1.1.2.2
--- /dev/null	Wed Mar 11 20:22:56 2015
+++ src/sys/arch/evbarm/conf/RPI2_INSTALL	Wed Mar 11 20:22:56 2015
@@ -0,0 +1,14 @@
+#	$NetBSD: RPI2_INSTALL,v 1.1.2.2 2015/03/11 20:22:56 snj Exp $
+#
+#	RPI2_INSTALL -- RPI2 kernel with installation-sized
+#	ramdisk
+#
+
+include "arch/evbarm/conf/RPI2"
+include "arch/evbarm/conf/INSTALL"
+
+no options	MEMORY_DISK_ROOT_SIZE
+options 	MEMORY_DISK_ROOT_SIZE=29696
+
+makeoptions	RAMDISKNAME=sshramdisk
+no makeoptions	DEBUG

Index: src/sys/arch/evbarm/rpi/rpi2_start.S
diff -u /dev/null src/sys/arch/evbarm/rpi/rpi2_start.S:1.1.2.2
--- /dev/null	Wed Mar 11 20:22:56 2015
+++ src/sys/arch/evbarm/rpi/rpi2_start.S	Wed Mar 11 20:22:56 2015
@@ -0,0 +1,277 @@
+/*-
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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_com.h"
+#include "opt_cpuoptions.h"
+#include "opt_cputypes.h"
+#include "opt_multiprocessor.h"
+#include "opt_arm_debug.h"
+
+#include <arm/asm.h>
+#include <arm/armreg.h>
+
+#include "assym.h"
+
+RCSID("$NetBSD: rpi2_start.S,v 1.1.2.2 2015/03/11 20:22:56 snj Exp $")
+
+#if defined(VERBOSE_INIT_ARM)
+#define	XPUTC(n)	mov r0, n; bl plputc
+#if KERNEL_BASE_VOFFSET == 0
+#define	XPUTC2(n)	mov r0, n; bl plputc
+#else
+#define XPUTC2(n)	mov r0, n; blx r11
+#endif
+#ifdef __ARMEB__
+#define COM_BSWAP
+#endif
+#define COM_MULT	4
+#else
+#define	XPUTC(n)
+#define	XPUTC2(n)
+#endif
+
+#define INIT_MEMSIZE	128
+#define	TEMP_L1_TABLE	(KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE)
+
+#define	MD_CPU_HATCH	_C_LABEL(bcm2836_cpu_hatch)
+
+/*
+ * Kernel start routine for RPI2 board.
+ * At this point, this code has been loaded into SDRAM
+ * and the MMU maybe on or maybe off.
+ */
+#ifdef KERNEL_BASES_EQUAL
+	.text
+#else
+	.section .start,"ax",%progbits
+#endif
+
+	.global	_C_LABEL(rpi_start)
+_C_LABEL(rpi_start):
+
+#ifdef __ARMEB__
+	setend	be			/* force big endian */
+#endif
+	mov	r9, #0
+
+	/* Move into supervisor mode and disable IRQs/FIQs. */
+	cpsid	if, #PSR_SVC32_MODE
+
+	/*
+	 * Save any arguments passed to us.
+	 */
+	movw	r4, #:lower16:rpi_boot_regs
+	movt	r4, #:upper16:rpi_boot_regs
+#if KERNEL_BASE_VOFFSET != 0
+	/*
+	 * But since .start is at 0x40000000 and .text is at 0x8000000, we
+	 * can't directly use the address that the linker gave us directly.
+	 * We have to adjust the address the linker gave us to get the to
+	 * the physical address.
+	 */
+	sub	r4, r4, #KERNEL_BASE_VOFFSET
+#endif
+
+	stmia	r4, {r0-r3}		// Save the arguments
+
+	/*
+	 * Turn on the SMP bit
+	 */
+	bl	cortex_init
+
+	/*
+	 * Set up a preliminary mapping in the MMU to allow us to run
+	 * at KERNEL_BASE with caches on.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+	movw	r1, #:lower16:.Lmmu_init_table
+	movt	r1, #:upper16:.Lmmu_init_table
+#if !defined(KERNEL_BASES_EQUAL)
+	sub	r8, r8, #KERNEL_BASE_VOFFSET
+#endif
+	bl	arm_boot_l1pt_init
+	XPUTC(#68)
+
+	/*
+	 * Turn on the MMU, Caches, etc.  Return to new enabled address space.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+#if KERNEL_BASE_VOFFSET == 0
+	bl	arm_cpuinit
+#else
+	/*
+	 * After the MMU is on, we can execute in the normal .text segment
+	 * so setup the lr to be in .text.  Cache the address for plputc
+	 * before we go.
+	 */
+#if defined(VERBOSE_INIT_ARM)
+	adr	r11, plputc		@ for XPUTC2
+#endif
+	movw	lr, #:lower16:1f
+	movt	lr, #:upper16:1f
+	b	arm_cpuinit
+
+	.pushsection .text,"ax",%progbits
+1:
+#endif
+	XPUTC2(#90)
+
+#if defined(MULTIPROCESSOR)
+	// Now spin up the second processors into the same state we are now.
+	XPUTC2(#77)		// 'M'
+	XPUTC2(#80)		// 'P'
+	XPUTC2(#60)		// '<'
+	// Make sure the cache is flushed out to RAM for the other CPUs
+	bl	_C_LABEL(armv7_dcache_wbinv_all)
+
+	XPUTC2(#62)		// '>'
+#endif /* MULTIPROCESSOR */
+	XPUTC2(#13)
+	XPUTC2(#10)
+
+	/*
+	 * Jump to start in locore.S, which in turn will call initarm and main.
+	 */
+	b	start
+
+	/* NOTREACHED */
+
+#ifndef KERNEL_BASES_EQUAL
+	.popsection
+#endif
+
+#include <arm/cortex/a9_mpsubr.S>
+
+#if defined(VERBOSE_INIT_ARM)
+
+#define	PL01XCOM_FR	0x18	/* Flag Register */
+#define	PL01XCOM_DR	0x00	/* Data Register */
+#define	PL01X_FR_TXFE	0x080	/* Transmit fifo empty */
+
+#define COM_DATA	PL01XCOM_DR
+#define	COM_LSR		PL01XCOM_FR
+#define	LSR_TSRE	PL01X_FR_TXFE
+#define COM_MULT	4
+
+#define CONSADDR	0x3f201000
+
+#define TIMO		0x25000
+#ifndef COM_MULT
+#define COM_MULT	1
+#endif
+	.global	_C_LABEL(plputc)
+_C_LABEL(plputc):
+
+	mov	r2, #TIMO
+	movw	r3, #:lower16:CONSADDR
+	movt	r3, #:upper16:CONSADDR
+1:
+#if COM_MULT == 1
+	ldrb	r1, [r3, #(COM_LSR*COM_MULT)]
+#else
+#if COM_MULT == 2
+	ldrh	r1, [r3, #(COM_LSR*COM_MULT)]
+#elif COM_MULT == 4
+	ldr	r1, [r3, #(COM_LSR*COM_MULT)]
+#endif
+#ifdef COM_BSWAP
+	lsr	r1, r1, #(COM_MULT-1)*8
+#endif
+#endif
+	tst	r1, #LSR_TSRE
+	bne	2f
+	subs	r2, r2, #1
+	bne	1b
+2:
+#if COM_MULT == 1
+	strb	r0, [r3, #COM_DATA]
+#else
+#ifdef COM_BSWAP
+	lsl	r0, r0, #(COM_MULT-1)*8
+#endif
+#if COM_MULT == 2
+	strh	r0, [r3, #COM_DATA]
+#else
+	str	r0, [r3, #COM_DATA]
+#endif
+#endif
+
+	mov	r2, #TIMO
+3:
+#if COM_MULT == 1
+	ldrb	r1, [r3, #(COM_LSR*COM_MULT)]
+#else
+#if COM_MULT == 2
+	ldrh	r1, [r3, #(COM_LSR*COM_MULT)]
+#elif COM_MULT == 4
+	ldr	r1, [r3, #(COM_LSR*COM_MULT)]
+#endif
+#ifdef COM_BSWAP
+	lsr	r1, r1, #(COM_MULT-1)*8
+#endif
+#endif
+	tst	r1, #LSR_TSRE
+	bne	4f
+	subs	r2, r2, #1
+	bne	3b
+4:
+	bx	lr
+#endif /* VERBOSE_INIT_ARM */
+
+
+.Lmmu_init_table:
+	/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */
+	MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+
+#if KERNEL_BASE_VOFFSET != 0
+	/* Map memory 1:1 VA to PA, write-back cacheable, shareable */
+	MMU_INIT(KERNEL_BASE - KERNEL_BASE_VOFFSET,
+		KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+#endif
+
+	/* Map the 16MB of peripherals */
+	MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
+	    (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+	/* Map the 16MB of peripherals */
+	MMU_INIT(RPI_KERNEL_IO_PBASE, RPI_KERNEL_IO_PBASE,
+	    (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+
+	/* end of table */
+	MMU_INIT(0, 0, 0, 0)
+
+END(_C_LABEL(rpi_start))
+

Reply via email to