Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Jan 2012 15:36:21 +0000 (UTC)
From:      Grzegorz Bernacki <gber@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r230813 - in projects/armv6/sys/arm: arm include mv/armadaxp
Message-ID:  <201201311536.q0VFaLX5042255@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gber
Date: Tue Jan 31 15:36:21 2012
New Revision: 230813
URL: http://svn.freebsd.org/changeset/base/230813

Log:
  Change AP cores startup procedure
  
  Cores were initialized and started one-by-one, thus causing problems with
  coherency fabric initialization.
  Now all AP cores are started at the same moment.
  
  Submitted by: Lukasz Plachno
  Obtained from: Marvell, Semihalf

Modified:
  projects/armv6/sys/arm/arm/mp_machdep.c
  projects/armv6/sys/arm/include/smp.h
  projects/armv6/sys/arm/mv/armadaxp/armadaxp_mp.c

Modified: projects/armv6/sys/arm/arm/mp_machdep.c
==============================================================================
--- projects/armv6/sys/arm/arm/mp_machdep.c	Tue Jan 31 15:32:05 2012	(r230812)
+++ projects/armv6/sys/arm/arm/mp_machdep.c	Tue Jan 31 15:36:21 2012	(r230813)
@@ -63,7 +63,7 @@ static int ipi_handler(void *arg);
 void set_stackptrs(int cpu);
 
 /* Temporary variables for init_secondary()  */
-void *dpcpu;
+void *dpcpu[MAXCPU - 1];
 
 /* Determine if we running MP machine */
 int
@@ -76,19 +76,12 @@ cpu_mp_probe(void)
 
 /* Start Application Processor via platform specific function */
 static int
-start_ap(int cpu)
+check_ap(void)
 {
-	int cpus, ms;
-
-	cpus = mp_naps;
-
-	dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
-	if (platform_mp_start_ap(cpu) != 0)
-		return (-1);			/* could not start AP */
+	uint32_t ms;
 
 	for (ms = 0; ms < 5000; ++ms) {
-		cpu_dcache_wbinv_all();
-		if (mp_naps > cpus)
+		if ((mp_naps + 1) == mp_ncpus)
 			return (0);		/* success */
 		else
 			DELAY(1000);
@@ -105,16 +98,22 @@ cpu_mp_start(void)
 
 	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
-	for (i = 1; i < mp_ncpus; i++) {
-		error = start_ap(i);
-		if (error) {
-			printf("AP #%d failed to start\n", i);
-			continue;
-		}
+	/* Reserve memory for application processors */
+	for(i = 0; i < (mp_ncpus - 1); i++)
+		dpcpu[i] = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
+
+	/* Initialize boot code and start up processors */
+	platform_mp_start_ap();
+
+	/*  Check if ap's started properly */
+	error = check_ap();
+	if (error)
+		printf("WARNING: Some AP's failed to start\n");
+	else
+		for (i = 1; i < mp_ncpus; i++)
+			CPU_SET(i, &all_cpus);
 
-		printf("AP #%d started\n", i);
-		CPU_SET(i, &all_cpus);
-	}
+	printf("%d AP started\n", mp_naps);
 }
 
 /* Introduce rest of cores to the world */
@@ -139,7 +138,7 @@ init_secondary(int cpu)
 	set_pcpu(pc);
 	pcpu_init(pc, cpu, sizeof(struct pcpu));
 
-	dpcpu_init(dpcpu, cpu);
+	dpcpu_init(dpcpu[cpu - 1], cpu);
 
 	/* Provide stack pointers for other processor modes. */
 	set_stackptrs(cpu);

Modified: projects/armv6/sys/arm/include/smp.h
==============================================================================
--- projects/armv6/sys/arm/include/smp.h	Tue Jan 31 15:32:05 2012	(r230812)
+++ projects/armv6/sys/arm/include/smp.h	Tue Jan 31 15:36:21 2012	(r230813)
@@ -27,7 +27,7 @@ int	pic_ipi_get(void);
 /* Platform interface */
 void	platform_mp_setmaxid(void);
 int	platform_mp_probe(void);
-int	platform_mp_start_ap(int cpuid);
+void	platform_mp_start_ap(void);
 
 void	platform_ipi_send(cpuset_t cpus, u_int ipi);
 

Modified: projects/armv6/sys/arm/mv/armadaxp/armadaxp_mp.c
==============================================================================
--- projects/armv6/sys/arm/mv/armadaxp/armadaxp_mp.c	Tue Jan 31 15:32:05 2012	(r230812)
+++ projects/armv6/sys/arm/mv/armadaxp/armadaxp_mp.c	Tue Jan 31 15:36:21 2012	(r230813)
@@ -121,65 +121,65 @@ initialize_coherency_fabric(void)
 }
 
 
-int
-platform_mp_start_ap(int cpuid)
+void
+platform_mp_start_ap(void)
 {
-	uint32_t reg, *ptr;
+	uint32_t reg, *ptr, cpu_num;
 
-	if (cpuid == 1) {
-		/* Copy boot code to SRAM */
-		*((unsigned int*)(0xf1020240)) = 0xffff0101;
-		*((unsigned int*)(0xf1008500)) = 0xffff0003;
-
-		pmap_kenter_nocache(0x880f0000, 0xffff0000);
-		reg = 0x880f0000;
-
-		for (ptr = (uint32_t *)mptramp; ptr < (uint32_t *)mpentry;
-		    ptr++, reg += 4)
-			*((uint32_t *)reg) = *ptr;
-
-		if (mp_ncpus > 1) {
-			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0);
-			reg &= 0x00ffffff;
-			reg |= 0x01000000;
-			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg);
-		}
-		if (mp_ncpus > 2) {
-			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
-			reg &= 0xff00ffff;
-			reg |= 0x00010000;
-			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
-		}
-		if (mp_ncpus > 3) {
-			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
-			reg &= 0x00ffffff;
-			reg |= 0x01000000;
-			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
-		}
-
-		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
-		reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21;
-		write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
-		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
+	/* Copy boot code to SRAM */
+	*((unsigned int*)(0xf1020240)) = 0xffff0101;
+	*((unsigned int*)(0xf1008500)) = 0xffff0003;
+
+	pmap_kenter_nocache(0x880f0000, 0xffff0000);
+	reg = 0x880f0000;
+
+	for (ptr = (uint32_t *)mptramp; ptr < (uint32_t *)mpentry;
+	    ptr++, reg += 4)
+		*((uint32_t *)reg) = *ptr;
+
+	if (mp_ncpus > 1) {
+		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0);
+		reg &= 0x00ffffff;
 		reg |= 0x01000000;
-		write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
-
-		DELAY(100);
-		reg &= ~(0xf << 21);
-		write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
-		DELAY(100);
-
-		bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0);
+		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg);
+	}
+	if (mp_ncpus > 2) {
+		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
+		reg &= 0xff00ffff;
+		reg |= 0x00010000;
+		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
+	}
+	if (mp_ncpus > 3) {
+		reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
+		reg &= 0x00ffffff;
+		reg |= 0x01000000;
+		write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
+	}
 
-		initialize_coherency_fabric();
+	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
+	reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21;
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
+	reg |= 0x01000000;
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+
+	DELAY(100);
+	reg &= ~(0xf << 21);
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+	DELAY(100);
+
+	bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0);
+
+	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
+		bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT,
+		    pmap_kextract(mpentry));
 
-	}
+	cpu_idcache_wbinv_all();
 
-	bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpuid), CPU_PMU_BOOT,
-	    pmap_kextract(mpentry));
-	bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpuid), 0);
+	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
+		bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0);
 
-	return (0);
+	initialize_coherency_fabric();
 }
 
 static int



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