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>