Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 May 2014 23:25:21 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r266379 - in stable/10/sys/arm: conf xilinx
Message-ID:  <201405172325.s4HNPLhd083844@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat May 17 23:25:20 2014
New Revision: 266379
URL: http://svnweb.freebsd.org/changeset/base/266379

Log:
  MFC 265099, 265148, 265690:
  
    Add SMP support for Zedboard.
  
    Use edge-triggered interrupts rather than polling loops to avoid missing
    transitions of the INIT_B line.  Also, release the mutex during uiomove().
  
    Convert the Zynq SoC support to the new routines for static device mapping.

Added:
  stable/10/sys/arm/xilinx/zy7_mp.c
     - copied unchanged from r265099, head/sys/arm/xilinx/zy7_mp.c
Modified:
  stable/10/sys/arm/conf/ZEDBOARD
  stable/10/sys/arm/xilinx/files.zynq7
  stable/10/sys/arm/xilinx/std.zynq7
  stable/10/sys/arm/xilinx/zy7_devcfg.c
  stable/10/sys/arm/xilinx/zy7_machdep.c
  stable/10/sys/arm/xilinx/zy7_reg.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/conf/ZEDBOARD
==============================================================================
--- stable/10/sys/arm/conf/ZEDBOARD	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/conf/ZEDBOARD	Sat May 17 23:25:20 2014	(r266379)
@@ -56,6 +56,7 @@ options 	SYSVSEM			# SYSV-style semaphor
 options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
 options 	FREEBSD_BOOT_LOADER
 options 	VFP			# vfp/neon
+options 	SMP			# Symmetric MultiProcessor Kernel
 
 # Debugging
 makeoptions	DEBUG=-g

Modified: stable/10/sys/arm/xilinx/files.zynq7
==============================================================================
--- stable/10/sys/arm/xilinx/files.zynq7	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/xilinx/files.zynq7	Sat May 17 23:25:20 2014	(r266379)
@@ -21,6 +21,7 @@ arm/xilinx/zy7_l2cache.c			standard
 arm/xilinx/zy7_bus_space.c			standard
 arm/xilinx/zy7_slcr.c				standard
 arm/xilinx/zy7_devcfg.c				standard
+arm/xilinx/zy7_mp.c				optional smp
 
 dev/cadence/if_cgem.c				optional if_cgem
 dev/sdhci/sdhci_fdt.c				optional sdhci

Modified: stable/10/sys/arm/xilinx/std.zynq7
==============================================================================
--- stable/10/sys/arm/xilinx/std.zynq7	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/xilinx/std.zynq7	Sat May 17 23:25:20 2014	(r266379)
@@ -20,3 +20,5 @@ makeoptions	KERNVIRTADDR=0xc0100000
 
 options		ARM_L2_PIPT
 
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15

Modified: stable/10/sys/arm/xilinx/zy7_devcfg.c
==============================================================================
--- stable/10/sys/arm/xilinx/zy7_devcfg.c	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/xilinx/zy7_devcfg.c	Sat May 17 23:25:20 2014	(r266379)
@@ -267,24 +267,35 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so
 
 	devcfg_ctl = RD4(sc, ZY7_DEVCFG_CTRL);
 
+	/* Clear sticky bits and set up INIT signal positive edge interrupt. */
+	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+	WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE);
+
 	/* Deassert PROG_B (active low). */
 	devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B;
 	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
 
-	/* Wait for INIT_B deasserted (active low). */
-	tries = 0;
-	while ((RD4(sc, ZY7_DEVCFG_STATUS) &
-		ZY7_DEVCFG_STATUS_PCFG_INIT) == 0) {
-		if (++tries >= 100)
-			return (EIO);
-		DELAY(5);
+	/*
+	 * Wait for INIT to assert.  If it is already asserted, we may not get
+	 * an edge interrupt so cancel it and continue.
+	 */
+	if ((RD4(sc, ZY7_DEVCFG_STATUS) &
+	     ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) {
+		/* Already asserted.  Cancel interrupt. */
+		WR4(sc, ZY7_DEVCFG_INT_MASK, ~0);
+	}
+	else {
+		/* Wait for positive edge interrupt. */
+		err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i1", hz);
+		if (err != 0)
+			return (err);
 	}
-
-	/* Reassert PROG_B. */
+	
+	/* Reassert PROG_B (active low). */
 	devcfg_ctl &= ~ZY7_DEVCFG_CTRL_PCFG_PROG_B;
 	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
 
-	/* Wait for INIT_B asserted. */
+	/* Wait for INIT deasserted.  This happens almost instantly. */
 	tries = 0;
 	while ((RD4(sc, ZY7_DEVCFG_STATUS) &
 		ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) {
@@ -293,7 +304,7 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so
 		DELAY(5);
 	}
 
-	/* Clear sticky bits and set up INIT_B positive edge interrupt. */
+	/* Clear sticky bits and set up INIT positive edge interrupt. */
 	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
 	WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE);
 
@@ -301,11 +312,11 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so
 	devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B;
 	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
 
-	/* Wait for INIT_B deasserted indicating FPGA internal initialization
-	 * is complete.  This takes much longer than the previous waits for
-	 * INIT_B transition (on the order of 700us).
+	/*
+	 * Wait for INIT asserted indicating FPGA internal initialization
+	 * is complete.
 	 */
-	err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7in", hz);
+	err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i2", hz);
 	if (err != 0)
 		return (err);
 
@@ -404,7 +415,9 @@ zy7_devcfg_write(struct cdev *dev, struc
 
 		/* uiomove the data from user buffer to our dma map. */
 		segsz = MIN(PAGE_SIZE, uio->uio_resid);
+		DEVCFG_SC_UNLOCK(sc);
 		err = uiomove(dma_mem, segsz, uio);
+		DEVCFG_SC_LOCK(sc);
 		if (err != 0)
 			break;
 

Modified: stable/10/sys/arm/xilinx/zy7_machdep.c
==============================================================================
--- stable/10/sys/arm/xilinx/zy7_machdep.c	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/xilinx/zy7_machdep.c	Sat May 17 23:25:20 2014	(r266379)
@@ -60,7 +60,7 @@ vm_offset_t
 initarm_lastaddr(void)
 {
 
-	return (ZYNQ7_PSIO_VBASE);
+	return (arm_devmap_lastaddr());
 }
 
 void
@@ -79,39 +79,18 @@ initarm_late_init(void)
 {
 }
 
-#define FDT_DEVMAP_SIZE 3
-static struct arm_devmap_entry fdt_devmap[FDT_DEVMAP_SIZE];
-
 /*
- * Construct pmap_devmap[] with DT-derived config data.
+ * Set up static device mappings.  Not strictly necessary -- simplebus will
+ * dynamically establish mappings as needed -- but doing it this way gets us
+ * nice efficient 1MB section mappings.
  */
 int
 initarm_devmap_init(void)
 {
-	int i = 0;
 
-	fdt_devmap[i].pd_va =	ZYNQ7_PSIO_VBASE;
-	fdt_devmap[i].pd_pa =	ZYNQ7_PSIO_HWBASE;
-	fdt_devmap[i].pd_size = ZYNQ7_PSIO_SIZE;
-	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
-	fdt_devmap[i].pd_cache = PTE_DEVICE;
-	i++;
-
-	fdt_devmap[i].pd_va =	ZYNQ7_PSCTL_VBASE;
-	fdt_devmap[i].pd_pa = 	ZYNQ7_PSCTL_HWBASE;
-	fdt_devmap[i].pd_size = ZYNQ7_PSCTL_SIZE;
-	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
-	fdt_devmap[i].pd_cache = PTE_DEVICE;
-	i++;
-
-	/* end of table */
-	fdt_devmap[i].pd_va = 0;
-	fdt_devmap[i].pd_pa = 0;
-	fdt_devmap[i].pd_size = 0;
-	fdt_devmap[i].pd_prot = 0;
-	fdt_devmap[i].pd_cache = 0;
+	arm_devmap_add_entry(ZYNQ7_PSIO_HWBASE, ZYNQ7_PSIO_SIZE);
+	arm_devmap_add_entry(ZYNQ7_PSCTL_HWBASE, ZYNQ7_PSCTL_SIZE);
 
-	arm_devmap_register_table(&fdt_devmap[0]);
 	return (0);
 }
 

Copied: stable/10/sys/arm/xilinx/zy7_mp.c (from r265099, head/sys/arm/xilinx/zy7_mp.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/sys/arm/xilinx/zy7_mp.c	Sat May 17 23:25:20 2014	(r266379, copy of r265099, head/sys/arm/xilinx/zy7_mp.c)
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 2013 Thomas Skibo.  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 ``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 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/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <arm/xilinx/zy7_reg.h>
+
+#define	ZYNQ7_CPU1_ENTRY	0xfffffff0
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+	mp_maxid = 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	mp_ncpus = 2;
+	return (1);
+}
+
+void    
+platform_mp_start_ap(void)
+{
+	bus_space_handle_t ocm_handle;
+
+	/* Map in magic location to give entry address to CPU1. */
+	if (bus_space_map(fdtbus_bs_tag, ZYNQ7_CPU1_ENTRY, 4,
+	    0, &ocm_handle) != 0)
+		panic("platform_mp_start_ap: Couldn't map OCM\n");
+
+	/* Write start address for CPU1. */
+	bus_space_write_4(fdtbus_bs_tag, ocm_handle, 0,
+	    pmap_kextract((vm_offset_t)mpentry));
+
+	/*
+	 * The SCU is enabled by the BOOTROM but I think the second CPU doesn't
+	 * turn on filtering until after the wake-up below. I think that's why
+	 * things don't work if I don't put these cache ops here.  Also, the
+	 * magic location, 0xfffffff0, isn't in the SCU's filtering range so it
+	 * needs a write-back too.
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	/* Wake up CPU1. */
+	armv7_sev();
+
+	bus_space_unmap(fdtbus_bs_tag, ocm_handle, 4);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}

Modified: stable/10/sys/arm/xilinx/zy7_reg.h
==============================================================================
--- stable/10/sys/arm/xilinx/zy7_reg.h	Sat May 17 23:21:53 2014	(r266378)
+++ stable/10/sys/arm/xilinx/zy7_reg.h	Sat May 17 23:25:20 2014	(r266379)
@@ -44,16 +44,13 @@
 #define ZYNQ7_PLGP1_SIZE	0x40000000
 
 /* I/O Peripheral registers. */
-#define ZYNQ7_PSIO_VBASE	0xE0000000
 #define ZYNQ7_PSIO_HWBASE	0xE0000000
 #define ZYNQ7_PSIO_SIZE		0x00300000
 
 /* UART0 and UART1 */
-#define ZYNQ7_UART0_VBASE	(ZYNQ7_PSIO_VBASE)
 #define ZYNQ7_UART0_HWBASE	(ZYNQ7_PSIO_HWBASE)
 #define ZYNQ7_UART0_SIZE	0x1000
 
-#define ZYNQ7_UART1_VBASE	(ZYNQ7_PSIO_VBASE+0x1000)
 #define ZYNQ7_UART1_HWBASE	(ZYNQ7_PSIO_HWBASE+0x1000)
 #define ZYNQ7_UART1_SIZE	0x1000
 
@@ -63,15 +60,12 @@
 #define ZYNQ7_SMC_SIZE		0x05000000
 
 /* SLCR, PS system, and CPU private registers combined in this region. */
-#define ZYNQ7_PSCTL_VBASE	0xF8000000
 #define ZYNQ7_PSCTL_HWBASE	0xF8000000
 #define ZYNQ7_PSCTL_SIZE	0x01000000
 
-#define ZYNQ7_SLCR_VBASE	(ZYNQ7_PSCTL_VBASE)
 #define ZYNQ7_SLCR_HWBASE	(ZYNQ7_PSCTL_HWBASE)
 #define ZYNQ7_SLCR_SIZE		0x1000
 
-#define ZYNQ7_DEVCFG_VBASE	(ZYNQ7_PSCTL_VBASE+0x7000)
 #define ZYNQ7_DEVCFG_HWBASE	(ZYNQ7_PSCTL_HWBASE+0x7000)
 #define ZYNQ7_DEVCFG_SIZE	0x1000
 



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