Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 May 2015 22:11:45 +0000 (UTC)
From:      Luiz Otavio O Souza <loos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282610 - in head/sys: arm/broadcom/bcm2835 arm/conf boot/fdt/dts/arm
Message-ID:  <201505072211.t47MBjQ8008175@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: loos
Date: Thu May  7 22:11:44 2015
New Revision: 282610
URL: https://svnweb.freebsd.org/changeset/base/282610

Log:
  Add the SMP support for Raspberry Pi 2 (BCM2836).
  
  Tested with the build of some ports and a buildworld.
  
  Submitted by:	Daisuke Aoyama <aoyama@peach.ne.jp>

Added:
  head/sys/arm/broadcom/bcm2835/bcm2836_mp.c   (contents, props changed)
Modified:
  head/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
  head/sys/arm/broadcom/bcm2835/bcm2836.c
  head/sys/arm/broadcom/bcm2835/files.bcm2836
  head/sys/arm/broadcom/bcm2835/std.bcm2836
  head/sys/arm/conf/RPI2
  head/sys/boot/fdt/dts/arm/rpi2.dts

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c	Thu May  7 22:11:44 2015	(r282610)
@@ -1425,7 +1425,10 @@ static int
 bcm2835_cpufreq_probe(device_t dev)
 {
 
+	if (device_get_unit(dev) != 0)
+		return (ENXIO);
 	device_set_desc(dev, "CPU Frequency Control");
+
 	return (0);
 }
 

Modified: head/sys/arm/broadcom/bcm2835/bcm2836.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2836.c	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/arm/broadcom/bcm2835/bcm2836.c	Thu May  7 22:11:44 2015	(r282610)
@@ -52,7 +52,9 @@ __FBSDID("$FreeBSD$");
 #define	ARM_LOCAL_INT_TIMER(n)		(0x40 + (n) * 4)
 #define	ARM_LOCAL_INT_MAILBOX(n)	(0x50 + (n) * 4)
 #define	ARM_LOCAL_INT_PENDING(n)	(0x60 + (n) * 4)
-#define	 INT_PENDING_MASK		0x0f
+#define	 INT_PENDING_MASK		0x01f
+#define	MAILBOX0_IRQ			4
+#define	MAILBOX0_IRQEN			(1 << 0)
 
 /*
  * A driver for features of the bcm2836.
@@ -141,12 +143,27 @@ void
 bcm2836_mask_irq(uintptr_t irq)
 {
 	uint32_t reg;
+#ifdef SMP
+	int cpu;
+#endif
 	int i;
 
-	for (i = 0; i < 4; i++) {
-		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
-		reg &= ~(1 << irq);
-		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+	if (irq < MAILBOX0_IRQ) {
+		for (i = 0; i < 4; i++) {
+			reg = bus_read_4(softc->sc_mem,
+			    ARM_LOCAL_INT_TIMER(i));
+			reg &= ~(1 << irq);
+			bus_write_4(softc->sc_mem,
+			    ARM_LOCAL_INT_TIMER(i), reg);
+		}
+#ifdef SMP
+	} else if (irq == MAILBOX0_IRQ) {
+		/* Mailbox 0 for IPI */
+		cpu = PCPU_GET(cpuid);
+		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
+		reg &= ~MAILBOX0_IRQEN;
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
+#endif
 	}
 }
 
@@ -154,12 +171,27 @@ void
 bcm2836_unmask_irq(uintptr_t irq)
 {
 	uint32_t reg;
+#ifdef SMP
+	int cpu;
+#endif
 	int i;
 
-	for (i = 0; i < 4; i++) {
-		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
-		reg |= (1 << irq);
-		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+	if (irq < MAILBOX0_IRQ) {
+		for (i = 0; i < 4; i++) {
+			reg = bus_read_4(softc->sc_mem,
+			    ARM_LOCAL_INT_TIMER(i));
+			reg |= (1 << irq);
+			bus_write_4(softc->sc_mem,
+			    ARM_LOCAL_INT_TIMER(i), reg);
+		}
+#ifdef SMP
+	} else if (irq == MAILBOX0_IRQ) {
+		/* Mailbox 0 for IPI */
+		cpu = PCPU_GET(cpuid);
+		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu));
+		reg |= MAILBOX0_IRQEN;
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg);
+#endif
 	}
 }
 

Added: head/sys/arm/broadcom/bcm2835/bcm2836_mp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/broadcom/bcm2835/bcm2836_mp.c	Thu May  7 22:11:44 2015	(r282610)
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (C) 2015 Daisuke Aoyama <aoyama@peach.ne.jp>
+ * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/smp.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#ifdef DEBUG
+#define	DPRINTF(fmt, ...) do {			\
+	printf("%s:%u: ", __func__, __LINE__);	\
+	printf(fmt, ##__VA_ARGS__);		\
+} while (0)
+#else
+#define	DPRINTF(fmt, ...)
+#endif
+
+#define	ARM_LOCAL_BASE		0x40000000
+#define	ARM_LOCAL_SIZE		0x00001000
+
+/* mailbox registers */
+#define	MBOXINTRCTRL_CORE(n)	(0x00000050 + (0x04 * (n)))
+#define	MBOX0SET_CORE(n)	(0x00000080 + (0x10 * (n)))
+#define	MBOX1SET_CORE(n)	(0x00000084 + (0x10 * (n)))
+#define	MBOX2SET_CORE(n)	(0x00000088 + (0x10 * (n)))
+#define	MBOX3SET_CORE(n)	(0x0000008C + (0x10 * (n)))
+#define	MBOX0CLR_CORE(n)	(0x000000C0 + (0x10 * (n)))
+#define	MBOX1CLR_CORE(n)	(0x000000C4 + (0x10 * (n)))
+#define	MBOX2CLR_CORE(n)	(0x000000C8 + (0x10 * (n)))
+#define	MBOX3CLR_CORE(n)	(0x000000CC + (0x10 * (n)))
+
+static bus_space_handle_t bs_periph;
+
+#define	BSRD4(addr) \
+	bus_space_read_4(fdtbus_bs_tag, bs_periph, (addr))
+#define	BSWR4(addr, val) \
+	bus_space_write_4(fdtbus_bs_tag, bs_periph, (addr), (val))
+
+void
+platform_mp_init_secondary(void)
+{
+
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+	DPRINTF("platform_mp_setmaxid\n");
+	if (mp_ncpus != 0)
+		return;
+
+	mp_ncpus = 4;
+	mp_maxid = mp_ncpus - 1;
+	DPRINTF("mp_maxid=%d\n", mp_maxid);
+}
+
+int
+platform_mp_probe(void)
+{
+
+	DPRINTF("platform_mp_probe\n");
+	CPU_SETOF(0, &all_cpus);
+	if (mp_ncpus == 0)
+		platform_mp_setmaxid();
+	return (mp_ncpus > 1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+	uint32_t val;
+	int i, retry;
+
+	DPRINTF("platform_mp_start_ap\n");
+
+	/* initialize */
+	if (bus_space_map(fdtbus_bs_tag, ARM_LOCAL_BASE, ARM_LOCAL_SIZE,
+	    0, &bs_periph) != 0)
+		panic("can't map local peripheral\n");
+	for (i = 0; i < mp_ncpus; i++) {
+		/* clear mailbox 0/3 */
+		BSWR4(MBOX0CLR_CORE(i), 0xffffffff);
+		BSWR4(MBOX3CLR_CORE(i), 0xffffffff);
+	}
+	wmb();
+
+	/* boot secondary CPUs */
+	for (i = 1; i < mp_ncpus; i++) {
+		/* set entry point to mailbox 3 */
+		BSWR4(MBOX3SET_CORE(i),
+		    (uint32_t)pmap_kextract((vm_offset_t)mpentry));
+		wmb();
+
+		/* wait for bootup */
+		retry = 1000;
+		do {
+			/* check entry point */
+			val = BSRD4(MBOX3CLR_CORE(i));
+			if (val == 0)
+				break;
+			DELAY(100);
+			retry--;
+			if (retry <= 0) {
+				printf("can't start for CPU%d\n", i);
+				break;
+			}
+		} while (1);
+
+		/* dsb and sev */
+		armv7_sev();
+
+		/* recode AP in CPU map */
+		CPU_SET(i, &all_cpus);
+	}
+
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+}
+
+void
+pic_ipi_send(cpuset_t cpus, u_int ipi)
+{
+	int i;
+
+	dsb();
+	for (i = 0; i < mp_ncpus; i++) {
+		if (CPU_ISSET(i, &cpus))
+			BSWR4(MBOX0SET_CORE(i), 1 << ipi);
+	}
+	wmb();
+}
+
+int
+pic_ipi_read(int i)
+{
+	uint32_t val;
+	int cpu, ipi;
+
+	cpu = PCPU_GET(cpuid);
+	dsb();
+	if (i != -1) {
+		val = BSRD4(MBOX0CLR_CORE(cpu));
+		if (val == 0)
+			return (0);
+		ipi = ffs(val) - 1;
+		return (ipi);
+	}
+	return (0x3ff);
+}
+
+void
+pic_ipi_clear(int ipi)
+{
+	int cpu;
+
+	cpu = PCPU_GET(cpuid);
+	dsb();
+	BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi);
+	wmb();
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}

Modified: head/sys/arm/broadcom/bcm2835/files.bcm2836
==============================================================================
--- head/sys/arm/broadcom/bcm2835/files.bcm2836	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/arm/broadcom/bcm2835/files.bcm2836	Thu May  7 22:11:44 2015	(r282610)
@@ -3,3 +3,4 @@
 arm/arm/generic_timer.c				standard
 
 arm/broadcom/bcm2835/bcm2836.c			standard
+arm/broadcom/bcm2835/bcm2836_mp.c		optional smp

Modified: head/sys/arm/broadcom/bcm2835/std.bcm2836
==============================================================================
--- head/sys/arm/broadcom/bcm2835/std.bcm2836	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/arm/broadcom/bcm2835/std.bcm2836	Thu May  7 22:11:44 2015	(r282610)
@@ -6,6 +6,7 @@ makeoptions	CONF_CFLAGS="-march=armv7a"
 options 	SOC_BCM2836
 
 options 	ARM_L2_PIPT
+options 	IPI_IRQ_START=76
 
 files	"../broadcom/bcm2835/files.bcm2836"
 files	"../broadcom/bcm2835/files.bcm283x"

Modified: head/sys/arm/conf/RPI2
==============================================================================
--- head/sys/arm/conf/RPI2	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/arm/conf/RPI2	Thu May  7 22:11:44 2015	(r282610)
@@ -25,7 +25,8 @@ include 	"../broadcom/bcm2835/std.rpi"
 include 	"../broadcom/bcm2835/std.bcm2836"
 
 options 	HZ=100
-options 	SCHED_4BSD		# 4BSD scheduler
+options 	SCHED_ULE		# ULE scheduler
+options 	SMP			# Enable multiple cores
 options 	PLATFORM
 
 # Debugging for use in -current

Modified: head/sys/boot/fdt/dts/arm/rpi2.dts
==============================================================================
--- head/sys/boot/fdt/dts/arm/rpi2.dts	Thu May  7 21:30:29 2015	(r282609)
+++ head/sys/boot/fdt/dts/arm/rpi2.dts	Thu May  7 22:11:44 2015	(r282610)
@@ -43,6 +43,24 @@
 			reg = <0xf00>;			/* CPU ID=0xf00 */
 			clock-frequency = <800000000>;	/* 800MHz */
 		};
+		cpu@1 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0xf01>;			/* CPU ID=0xf01 */
+			clock-frequency = <800000000>;	/* 800MHz */
+		};
+		cpu@2 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0xf02>;			/* CPU ID=0xf02 */
+			clock-frequency = <800000000>;	/* 800MHz */
+		};
+		cpu@3 {
+			compatible = "arm,cortex-a7";
+			device_type = "cpu";
+			reg = <0xf03>;			/* CPU ID=0xf03 */
+			clock-frequency = <800000000>;	/* 800MHz */
+		};
 	};
 
 	memory {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505072211.t47MBjQ8008175>