Module Name: src Committed By: bouyer Date: Sun Jan 16 12:58:24 UTC 2011
Modified Files: src/sys/arch/sparc/sparc [netbsd-5]: cpu.c cpuvar.h db_interface.c locore.s pmap.c Log Message: Pull up following revision(s) (requested by mrg in ticket #1527): sys/arch/sparc/sparc/pmap.c: revision 1.327, 1.328 sys/arch/sparc/sparc/cpuvar.h: revision 1.77 sys/arch/sparc/sparc/locore.s: revision 1.245 sys/arch/sparc/sparc/cpu.c: revision 1.214 sys/arch/sparc/sparc/db_interface.c: revision 1.84 - retire union cpu_info_pg - allocate space for each cpu_info{} in pmap_bootstrap - remap cpu0's space into the PA currently in CPUINFO_VA - cpus[] becomes an array of pointers to cpu_info{}, easy to traverse - only call kernel lock for IPL_VM interrupts (? as implemented on x86 and sparc64) - revert a minor part of locore.s:1.241 - in cpu_hatch(), set %sp to near the middle of the interrupt stack. we only need a %sp until we get to run an MI thread (own idlelwp or real code) we still waste one page of space, but this gets SMP much closer to actually working again. fix a LOCKDEBUG problem from the previous: need to call pmap_kremove() on a pre-existing mapping, before installing a new one. To generate a diff of this commit: cvs rdiff -u -r1.211.8.1 -r1.211.8.2 src/sys/arch/sparc/sparc/cpu.c cvs rdiff -u -r1.75.10.1 -r1.75.10.2 src/sys/arch/sparc/sparc/cpuvar.h cvs rdiff -u -r1.79.4.1 -r1.79.4.2 src/sys/arch/sparc/sparc/db_interface.c cvs rdiff -u -r1.244.8.1 -r1.244.8.2 src/sys/arch/sparc/sparc/locore.s cvs rdiff -u -r1.322.20.2 -r1.322.20.3 src/sys/arch/sparc/sparc/pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/sparc/cpu.c diff -u src/sys/arch/sparc/sparc/cpu.c:1.211.8.1 src/sys/arch/sparc/sparc/cpu.c:1.211.8.2 --- src/sys/arch/sparc/sparc/cpu.c:1.211.8.1 Sat May 30 16:57:18 2009 +++ src/sys/arch/sparc/sparc/cpu.c Sun Jan 16 12:58:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.211.8.1 2009/05/30 16:57:18 snj Exp $ */ +/* $NetBSD: cpu.c,v 1.211.8.2 2011/01/16 12:58:23 bouyer Exp $ */ /* * Copyright (c) 1996 @@ -52,7 +52,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.211.8.1 2009/05/30 16:57:18 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.211.8.2 2011/01/16 12:58:23 bouyer Exp $"); #include "opt_multiprocessor.h" #include "opt_lockdebug.h" @@ -103,7 +103,7 @@ int sparc_ncpus; /* # of CPUs detected by PROM */ #ifdef MULTIPROCESSOR -union cpu_info_pg *cpus; +struct cpu_info *cpus[4]; /* we only support 4 CPUs. */ u_int cpu_ready_mask; /* the set of CPUs marked as READY */ #endif @@ -156,10 +156,10 @@ getcpuinfo(cpi, node); /* - * Arrange pcb and interrupt stack. + * Arrange interrupt stack. This cpu will also abuse the bottom + * half of the interrupt stack before it gets to run its idle LWP. */ - intstack = uvm_km_alloc(kernel_map, INT_STACK_SIZE, - 0, UVM_KMF_WIRED); + intstack = uvm_km_alloc(kernel_map, INT_STACK_SIZE, 0, UVM_KMF_WIRED); if (intstack == 0) panic("%s: no uspace/intstack", __func__); cpi->eintstack = (void*)(intstack + INT_STACK_SIZE); @@ -339,7 +339,7 @@ getcpuinfo(&cpuinfo, node); #if defined(MULTIPROCESSOR) - cpi = sc->sc_cpuinfo = cpuinfo.ci_self; + cpi = sc->sc_cpuinfo = cpus[idx]; #else /* The `local' VA is global for uniprocessor. */ cpi = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA; @@ -362,7 +362,7 @@ /* * Initialise this cpu's cpu_info. */ - cpi = sc->sc_cpuinfo = &cpus[idx].ci; + cpi = sc->sc_cpuinfo = cpus[idx]; init_cpuinfo(cpi, node); /* Index: src/sys/arch/sparc/sparc/cpuvar.h diff -u src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.1 src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.2 --- src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.1 Sat May 30 16:57:18 2009 +++ src/sys/arch/sparc/sparc/cpuvar.h Sun Jan 16 12:58:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuvar.h,v 1.75.10.1 2009/05/30 16:57:18 snj Exp $ */ +/* $NetBSD: cpuvar.h,v 1.75.10.2 2011/01/16 12:58:23 bouyer Exp $ */ /* * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -416,7 +416,7 @@ #define CPU_INFO_ITERATOR int #ifdef MULTIPROCESSOR -#define CPU_INFO_FOREACH(cii, cp) cii = 0; cp = &cpus[cii].ci, cii < sparc_ncpus; cii++ +#define CPU_INFO_FOREACH(cii, cp) cii = 0; cp = cpus[cii], cii < sparc_ncpus; cii++ #else #define CPU_INFO_FOREACH(cii, cp) (void)cii, cp = curcpu(); cp != NULL; cp = NULL #endif @@ -473,11 +473,7 @@ #define CPU_MID2CPUNO(mid) ((mid) != 0 ? (mid) - 8 : 0) #ifdef MULTIPROCESSOR -union cpu_info_pg { - struct cpu_info ci; /* cpu info (aliased (per cpu) to CPUINFO_VA */ - char pad[32 * 1024]; /* XXX: force 32K alignment for now */ -}; /* SMP capable cpu types */ -extern union cpu_info_pg *cpus; +extern struct cpu_info *cpus[]; extern u_int cpu_ready_mask; /* the set of CPUs marked as READY */ #endif Index: src/sys/arch/sparc/sparc/db_interface.c diff -u src/sys/arch/sparc/sparc/db_interface.c:1.79.4.1 src/sys/arch/sparc/sparc/db_interface.c:1.79.4.2 --- src/sys/arch/sparc/sparc/db_interface.c:1.79.4.1 Sat May 30 16:57:18 2009 +++ src/sys/arch/sparc/sparc/db_interface.c Sun Jan 16 12:58:24 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: db_interface.c,v 1.79.4.1 2009/05/30 16:57:18 snj Exp $ */ +/* $NetBSD: db_interface.c,v 1.79.4.2 2011/01/16 12:58:24 bouyer Exp $ */ /* * Mach Operating System @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.79.4.1 2009/05/30 16:57:18 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.79.4.2 2011/01/16 12:58:24 bouyer Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -463,7 +463,7 @@ db_printf("%ld: CPU out of range\n", addr); return; } - ci = &cpus[addr].ci; + ci = cpus[addr]; if (ci == NULL) { db_printf("CPU %ld not configured\n", addr); return; Index: src/sys/arch/sparc/sparc/locore.s diff -u src/sys/arch/sparc/sparc/locore.s:1.244.8.1 src/sys/arch/sparc/sparc/locore.s:1.244.8.2 --- src/sys/arch/sparc/sparc/locore.s:1.244.8.1 Sat Jan 9 01:43:51 2010 +++ src/sys/arch/sparc/sparc/locore.s Sun Jan 16 12:58:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.244.8.1 2010/01/09 01:43:51 snj Exp $ */ +/* $NetBSD: locore.s,v 1.244.8.2 2011/01/16 12:58:23 bouyer Exp $ */ /* * Copyright (c) 1996 Paul Kranenburg @@ -2537,11 +2537,10 @@ * XXX Must not happen for fast soft interrupts! */ cmp %l3, IPL_VM - bgeu 0f + bne 3f st %fp, [%sp + CCFSZ + 16] call _C_LABEL(intr_lock_kernel) nop -0: #endif b 3f @@ -2565,7 +2564,7 @@ #if defined(MULTIPROCESSOR) cmp %l3, IPL_VM - bgeu 0f + bne 0f nop call _C_LABEL(intr_unlock_kernel) nop @@ -2732,7 +2731,7 @@ #if defined(MULTIPROCESSOR) /* Grab the kernel lock for interrupt levels =< IPL_VM */ cmp %l3, IPL_VM - bgeu 3f + bne 3f st %fp, [%sp + CCFSZ + 16] call _C_LABEL(intr_lock_kernel) nop @@ -2772,7 +2771,7 @@ 4: #if defined(MULTIPROCESSOR) cmp %l3, IPL_VM - bgeu 0f + bne 0f nop call _C_LABEL(intr_unlock_kernel) nop @@ -4602,12 +4601,12 @@ wr %g6, 0, %tbr nop; nop; nop ! paranoia - /* Set up a stack */ + /* Set up a stack. We use the bottom half of the interrupt stack */ set USRSTACK - CCFSZ, %fp ! as if called from user code sethi %hi(_EINTSTACKP), %o0 ld [%o0 + %lo(_EINTSTACKP)], %o0 - set USPACE - CCFSZ - 80, %sp - add %sp, %o0, %sp + set (INT_STACK_SIZE/2) + CCFSZ + 80, %sp + sub %o0, %sp, %sp /* Enable traps */ rd %psr, %l0 Index: src/sys/arch/sparc/sparc/pmap.c diff -u src/sys/arch/sparc/sparc/pmap.c:1.322.20.2 src/sys/arch/sparc/sparc/pmap.c:1.322.20.3 --- src/sys/arch/sparc/sparc/pmap.c:1.322.20.2 Sun Nov 15 05:58:38 2009 +++ src/sys/arch/sparc/sparc/pmap.c Sun Jan 16 12:58:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.322.20.2 2009/11/15 05:58:38 snj Exp $ */ +/* $NetBSD: pmap.c,v 1.322.20.3 2011/01/16 12:58:23 bouyer Exp $ */ /* * Copyright (c) 1996 @@ -56,7 +56,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.322.20.2 2009/11/15 05:58:38 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.322.20.3 2011/01/16 12:58:23 bouyer Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -3470,7 +3470,8 @@ vaddr_t va; #ifdef MULTIPROCESSOR vsize_t off; - struct vm_page *pg; + size_t cpuinfo_len; + uint8_t *cpuinfo_data; #endif /* @@ -3541,6 +3542,22 @@ p += ncontext * sizeof *ci; bzero((void *)ci, (u_int)p - (u_int)ci); +#if defined(MULTIPROCESSOR) + /* + * allocate the rest of the cpu_info{} area. note we waste the + * first one to get a VA space. + */ + p = (p + NBPG - 1) & ~PGOFSET; + cpuinfo_data = (uint8_t *)p; + cpuinfo_len = ((sizeof(struct cpu_info) + NBPG - 1) & ~PGOFSET); + p += (cpuinfo_len * sparc_ncpus); + prom_printf("extra cpus: %p, p: %p, gap start: %p, gap end: %p\n", + cpuinfo_data, p, etext_gap_start, etext_gap_end); + + /* XXX we waste the first one */ + memset(cpuinfo_data + cpuinfo_len, 0, cpuinfo_len * (sparc_ncpus - 1)); +#endif + /* * Set up the `constants' for the call to vm_init() * in main(). All pages beginning at p (rounded up to @@ -3784,62 +3801,32 @@ mmu_install_tables(&cpuinfo); #ifdef MULTIPROCESSOR - /* Allocate VA for all the cpu_info structurs */ - cpus = (union cpu_info_pg*)uvm_km_alloc(kernel_map, - sizeof cpus[sparc_ncpus], 32*1024, UVM_KMF_VAONLY); /* - * Add an alias mapping for the CPUINFO_VA allocation created - * early during bootstrap for the first CPU + * Remap cpu0 from CPUINFO_VA to the new correct value, wasting the + * backing pages we allocated above XXX. */ - off = 0; - for (va = (vaddr_t)&cpus[0].ci; + for (off = 0, va = (vaddr_t)cpuinfo_data; off < sizeof(struct cpu_info); va += NBPG, off += NBPG) { paddr_t pa = PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off); + prom_printf("going to pmap_kenter_pa(va=%p, pa=%p)\n", va, pa); + pmap_kremove(va, NBPG); pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); } - /* - * Now allocate memory for all other CPUs cpu_info and map - * it into the coresponding space in the cpus array. We will - * later duplicate the mapping into CPUINFO_VA. - */ - for (i = 1; i < sparc_ncpus; i++) { - off = 0; - for (va = (vaddr_t)&cpus[i].ci; - off < sizeof(struct cpu_info); - va += NBPG, off += NBPG) { - pg = uvm_pagealloc(NULL, 0, NULL, 0); - paddr_t pa = VM_PAGE_TO_PHYS(pg); - pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); - } - } - - /* clear new cpu infos */ - prom_printf("clearing other cpus cpu info\n"); - memset(&cpus[1].ci, 0, (sparc_ncpus-1)*sizeof(union cpu_info_pg)); - /* setup self refernces, and cpu "cpuinfo" */ - prom_printf("setting cpus self reference and mapping\n"); + /* + * Setup the cpus[] array and the ci_self links. + */ + prom_printf("setting cpus self reference\n"); for (i = 0; i < sparc_ncpus; i++) { - - prom_printf("going to set cpu%d ci_self address: %p\n", i, &cpus[i].ci); - cpus[i].ci.ci_self = &cpus[i].ci; - - /* mapped above. */ - if (i == 0) - continue; - - off = 0; - for (va = (vaddr_t)&cpus[i].ci; - off < sizeof(struct cpu_info); - va += NBPG, off += NBPG) { - paddr_t pa = PMAP_BOOTSTRAP_VA2PA(va + off); - prom_printf("going to pmap_kenter_pa(va=%p, pa=%p)\n", va, pa); - pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); - } + cpus[i] = (struct cpu_info *)(cpuinfo_data + (cpuinfo_len * i)); + cpus[i]->ci_self = cpus[i]; + prom_printf("set cpu%d ci_self address: %p\n", i, cpus[i]); } #endif + pmap_update(pmap_kernel()); + prom_printf("pmap_bootstrap4m done\n"); } static u_long prom_ctxreg; @@ -4451,7 +4438,7 @@ #ifdef MULTIPROCESSOR /* Invalidate level 1 PTP entries on all CPUs */ for (; n < sparc_ncpus; n++) { - if ((cpus[n].ci.flags & CPUFLG_HATCHED) == 0) + if ((cpus[n]->flags & CPUFLG_HATCHED) == 0) continue; #endif setpgt4m(&pm->pm_reg_ptps[n][vr], SRMMU_TEINVALID); @@ -6288,7 +6275,7 @@ #endif { #if defined(MULTIPROCESSOR) - if ((cpus[i].ci.flags & CPUFLG_HATCHED) == 0) + if ((cpus[i]->flags & CPUFLG_HATCHED) == 0) continue; #endif setpgt4m(&pm->pm_reg_ptps[i][vr],