Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Mar 2012 01:20:46 +0000 (UTC)
From:      Olivier Houchard <cognet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r232422 - in projects/armv6/sys/arm: arm include mv mv/armadaxp
Message-ID:  <201203030120.q231Kkv9056241@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cognet
Date: Sat Mar  3 01:20:46 2012
New Revision: 232422
URL: http://svn.freebsd.org/changeset/base/232422

Log:
  - We can't rely on the initial pagetable still being setted up, maybe we
  reused the memory, instead, allocate a temporary page table, map the
  kernel into it, and make the APs use it.
  - Make it so we can use multiple IRQs for IPI
  - Add a new function, platform_mp_init_secondary(), which will be called
  for each AP, and do platform-specific init stuff, such as setting up the
  GIC for the AP.

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
  projects/armv6/sys/arm/mv/mpic.c

Modified: projects/armv6/sys/arm/arm/mp_machdep.c
==============================================================================
--- projects/armv6/sys/arm/arm/mp_machdep.c	Sat Mar  3 01:17:13 2012	(r232421)
+++ projects/armv6/sys/arm/arm/mp_machdep.c	Sat Mar  3 01:20:46 2012	(r232422)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sched.h>
 #include <sys/smp.h>
 #include <sys/ktr.h>
+#include <sys/malloc.h>
 
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
@@ -47,7 +48,11 @@ __FBSDID("$FreeBSD$");
 #include <machine/pcb.h>
 #include <machine/pte.h>
 #include <machine/intr.h>
+#include <machine/vmparam.h>
 
+#include "opt_smp.h"
+
+void *temp_pagetable;
 extern struct pcpu __pcpu[];
 /* used to hold the AP's until we are ready to release them */
 struct mtx ap_boot_mtx;
@@ -90,17 +95,38 @@ check_ap(void)
 	return (-2);
 }
 
+extern unsigned char _end[];
+
 /* Initialize and fire up non-boot processors */
 void
 cpu_mp_start(void)
 {
 	int error, i;
+	vm_offset_t temp_pagetable_va;
+	vm_paddr_t addr, addr_end;
 
 	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
 	/* Reserve memory for application processors */
 	for(i = 0; i < (mp_ncpus - 1); i++)
 		dpcpu[i] = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
+	temp_pagetable_va = (vm_offset_t)contigmalloc(L1_TABLE_SIZE,
+	    M_TEMP, 0, 0x0, 0xffffffff, L1_TABLE_SIZE, 0);
+	addr = KERNPHYSADDR;
+	addr_end = (vm_offset_t)&_end - KERNVIRTADDR + KERNPHYSADDR;
+	addr_end &= ~L1_S_OFFSET;
+	addr_end += L1_S_SIZE;
+	bzero((void *)temp_pagetable_va,  L1_TABLE_SIZE);
+	for (addr = KERNPHYSADDR; addr <= addr_end; addr += L1_S_SIZE) { 
+		((int *)(temp_pagetable_va))[addr >> L1_S_SHIFT] =
+		    L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
+		((int *)(temp_pagetable_va))[(addr -
+			KERNPHYSADDR + KERNVIRTADDR) >> L1_S_SHIFT] = 
+		    L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
+	}
+	temp_pagetable = (void*)(vtophys(temp_pagetable_va));
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
 
 	/* Initialize boot code and start up processors */
 	platform_mp_start_ap();
@@ -113,7 +139,7 @@ cpu_mp_start(void)
 		for (i = 1; i < mp_ncpus; i++)
 			CPU_SET(i, &all_cpus);
 
-	printf("%d AP started\n", mp_naps);
+	contigfree((void *)temp_pagetable_va, L1_TABLE_SIZE, M_TEMP);
 }
 
 /* Introduce rest of cores to the world */
@@ -129,9 +155,9 @@ init_secondary(int cpu)
 {
 	struct pcpu *pc;
 	uint32_t loop_counter;
+	int start = 0, end = 0;
 
 	cpu_setup(NULL);
-
 	setttb(pmap_pa);
 	cpu_tlb_flushID();
 
@@ -169,7 +195,17 @@ init_secondary(int cpu)
 	mtx_unlock_spin(&ap_boot_mtx);
 
 	/* Enable ipi */
-	arm_unmask_irq(0);
+#ifdef IPI_IRQ_START
+	start = IPI_IRQ_START;
+#ifdef IPI_IRQ_END
+  	end = IPI_IRQ_END;
+#else
+	end = IPI_IRQ_START;
+#endif
+#endif
+				
+	for (int i = start; i <= end; i++)
+		arm_unmask_irq(i);
 	enable_interrupts(I32_bit);
 
 	loop_counter = 0;
@@ -179,11 +215,11 @@ init_secondary(int cpu)
 		if (loop_counter == 1000)
 			CTR0(KTR_SMP, "AP still wait for smp_started");
 	}
-
 	/* Start per-CPU event timers. */
 	cpu_initclocks_ap();
 
 	CTR0(KTR_SMP, "go into scheduler");
+	platform_mp_init_secondary();
 
 	/* Enter the scheduler */
 	sched_throw(NULL);
@@ -199,7 +235,7 @@ ipi_handler(void *arg)
 
 	cpu = PCPU_GET(cpuid);
 
-	ipi = pic_ipi_get();
+	ipi = pic_ipi_get((int)arg);
 
 	while ((ipi != 0x3ff)) {
 		switch (ipi) {
@@ -250,7 +286,7 @@ ipi_handler(void *arg)
 		}
 
 		pic_ipi_clear(ipi);
-		ipi = pic_ipi_get();
+		ipi = pic_ipi_get(-1);
 	}
 
 	return (FILTER_HANDLED);
@@ -260,19 +296,34 @@ static void
 release_aps(void *dummy __unused)
 {
 	uint32_t loop_counter;
+	int start = 0, end = 0;
 
 	if (mp_ncpus == 1)
 		return;
+#ifdef IPI_IRQ_START
+	start = IPI_IRQ_START;
+#ifdef IPI_IRQ_END
+	end = IPI_IRQ_END;
+#else
+	end = IPI_IRQ_START;
+#endif
+#endif
+
+	for (int i = start; i <= end; i++) {
+		/*
+		 * IPI handler
+		 */
+		/* 
+		 * Use 0xdeadbeef as the argument value for irq 0,
+		 * if we used 0, the intr code will give the trap frame
+		 * pointer instead.
+		 */
+		arm_setup_irqhandler("ipi", ipi_handler, NULL, (void *)i, i,
+		    INTR_TYPE_MISC | INTR_EXCL, NULL);
 
-	/*
-	 * IPI handler
-	 */
-	arm_setup_irqhandler("ipi", ipi_handler, NULL, NULL, 0,
-	    INTR_TYPE_MISC | INTR_EXCL, NULL);
-
-	/* Enable ipi */
-	arm_unmask_irq(0);
-
+		/* Enable ipi */
+		arm_unmask_irq(i);
+	}
 	atomic_store_rel_int(&aps_ready, 1);
 
 	printf("Release APs\n");
@@ -282,7 +333,6 @@ release_aps(void *dummy __unused)
 			return;
 		DELAY(1000);
 	}
-
 	printf("AP's not started\n");
 }
 

Modified: projects/armv6/sys/arm/include/smp.h
==============================================================================
--- projects/armv6/sys/arm/include/smp.h	Sat Mar  3 01:17:13 2012	(r232421)
+++ projects/armv6/sys/arm/include/smp.h	Sat Mar  3 01:20:46 2012	(r232422)
@@ -22,12 +22,13 @@ void	ipi_selected(cpuset_t cpus, u_int i
 /* PIC interface */
 void	pic_ipi_send(cpuset_t cpus, u_int ipi);
 void	pic_ipi_clear(int ipi);
-int	pic_ipi_get(void);
+int	pic_ipi_get(int arg);
 
 /* Platform interface */
 void	platform_mp_setmaxid(void);
 int	platform_mp_probe(void);
 void	platform_mp_start_ap(void);
+void	platform_mp_init_secondary(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	Sat Mar  3 01:17:13 2012	(r232421)
+++ projects/armv6/sys/arm/mv/armadaxp/armadaxp_mp.c	Sat Mar  3 01:20:46 2012	(r232422)
@@ -101,6 +101,11 @@ platform_mp_probe(void)
 	return (mp_ncpus > 1);
 }
 
+void
+platform_mp_init_secondary(void)
+{
+}
+
 void mpentry(void);
 void mptramp(void);
 

Modified: projects/armv6/sys/arm/mv/mpic.c
==============================================================================
--- projects/armv6/sys/arm/mv/mpic.c	Sat Mar  3 01:17:13 2012	(r232421)
+++ projects/armv6/sys/arm/mv/mpic.c	Sat Mar  3 01:20:46 2012	(r232422)
@@ -281,7 +281,7 @@ pic_ipi_send(cpuset_t cpus, u_int ipi)
 }
 
 int
-pic_ipi_get(void)
+pic_ipi_get(int i __unused)
 {
 	uint32_t val;
 



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