From owner-svn-src-projects@FreeBSD.ORG Sat Mar 3 01:20:47 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 3DA791065672; Sat, 3 Mar 2012 01:20:47 +0000 (UTC) (envelope-from cognet@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2C5C58FC0A; Sat, 3 Mar 2012 01:20:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q231KlUb056246; Sat, 3 Mar 2012 01:20:47 GMT (envelope-from cognet@svn.freebsd.org) Received: (from cognet@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q231Kkv9056241; Sat, 3 Mar 2012 01:20:46 GMT (envelope-from cognet@svn.freebsd.org) Message-Id: <201203030120.q231Kkv9056241@svn.freebsd.org> From: Olivier Houchard Date: Sat, 3 Mar 2012 01:20:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232422 - in projects/armv6/sys/arm: arm include mv mv/armadaxp X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Mar 2012 01:20:47 -0000 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 #include #include +#include #include #include @@ -47,7 +48,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#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;