Index: sys/arch/sparc/sparc/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v retrieving revision 1.211.8.2 diff -p -r1.211.8.2 cpu.c *** sys/arch/sparc/sparc/cpu.c 16 Jan 2011 12:58:23 -0000 1.211.8.2 --- sys/arch/sparc/sparc/cpu.c 28 Jan 2011 08:02:23 -0000 *************** char cpu_model[100]; /* machine model *** 102,111 **** extern char machine_model[]; int sparc_ncpus; /* # of CPUs detected by PROM */ ! #ifdef MULTIPROCESSOR ! struct cpu_info *cpus[4]; /* we only support 4 CPUs. */ ! u_int cpu_ready_mask; /* the set of CPUs marked as READY */ ! #endif /* The CPU configuration driver. */ static void cpu_mainbus_attach(struct device *, struct device *, void *); --- 102,108 ---- extern char machine_model[]; int sparc_ncpus; /* # of CPUs detected by PROM */ ! struct cpu_info *cpus[_MAXNCPU]; /* we only support 4 CPUs. */ /* The CPU configuration driver. */ static void cpu_mainbus_attach(struct device *, struct device *, void *); *************** void fpu_init(struct cpu_info *); *** 136,178 **** #define SRMMU_VERS(mmusr) (((mmusr) >> 24) & 0xf) int bootmid; /* Module ID of boot CPU */ - #if defined(MULTIPROCESSOR) - void cpu_spinup(struct cpu_info *); - static void init_cpuinfo(struct cpu_info *, int); - - int go_smp_cpus = 0; /* non-primary CPUs wait for this to go */ - - /* lock this to send IPI's */ - struct simplelock xpmsg_lock = SIMPLELOCK_INITIALIZER; - - static void - init_cpuinfo(struct cpu_info *cpi, int node) - { - vaddr_t intstack, va; - - /* - * Finish initialising this cpu_info. - */ - getcpuinfo(cpi, node); - - /* - * 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); - if (intstack == 0) - panic("%s: no uspace/intstack", __func__); - cpi->eintstack = (void*)(intstack + INT_STACK_SIZE); - - /* Allocate virtual space for pmap page_copy/page_zero */ - va = uvm_km_alloc(kernel_map, 2*PAGE_SIZE, 0, UVM_KMF_VAONLY); - if (va == 0) - panic("%s: no virtual space", __func__); - - cpi->vpage[0] = (void *)(va + 0); - cpi->vpage[1] = (void *)(va + PAGE_SIZE); - } - #endif /* MULTIPROCESSOR */ #ifdef notdef /* --- 133,138 ---- *************** static char *iu_vendor[16] = { *** 199,204 **** --- 159,179 ---- }; #endif + #if defined(MULTIPROCESSOR) + u_int cpu_ready_mask; /* the set of CPUs marked as READY */ + void cpu_spinup(struct cpu_info *); + static void cpu_attach_non_boot(struct cpu_softc *, struct cpu_info *, int); + + int go_smp_cpus = 0; /* non-primary CPUs wait for this to go */ + + /* + * This must be locked around all message transactions to ensure only + * one CPU is generating them. + */ + static kmutex_t xpmsg_mutex; + + #endif /* MULTIPROCESSOR */ + /* * 4/110 comment: the 4/110 chops off the top 4 bits of an OBIO address. * this confuses autoconf. for example, if you try and map *************** cpu_cpuunit_attach(struct device *parent *** 326,331 **** --- 301,307 ---- static void cpu_attach(struct cpu_softc *sc, int node, int mid) { + char buf[100]; struct cpu_info *cpi; int idx; static int cpu_attach_count = 0; *************** cpu_attach(struct cpu_softc *sc, int nod *** 335,403 **** * (see autoconf.c and cpuunit.c) */ idx = cpu_attach_count++; - if (cpu_attach_count == 1) { - getcpuinfo(&cpuinfo, node); - - #if defined(MULTIPROCESSOR) - cpi = sc->sc_cpuinfo = cpus[idx]; - #else - /* The `local' VA is global for uniprocessor. */ - cpi = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA; - #endif - cpi->master = 1; - cpi->eintstack = eintstack; - /* Note: `curpcb' is set to `proc0' in locore */ - - /* - * If we haven't been able to determine the Id of the - * boot CPU, set it now. In this case we can only boot - * from CPU #0 (see also the CPU attach code in autoconf.c) - */ - if (bootmid == 0) - bootmid = mid; - } else { - #if defined(MULTIPROCESSOR) - int error; - - /* - * Initialise this cpu's cpu_info. - */ - cpi = sc->sc_cpuinfo = cpus[idx]; - init_cpuinfo(cpi, node); ! /* ! * Call the MI attach which creates an idle LWP for us. ! */ ! error = mi_cpu_attach(cpi); ! if (error != 0) { ! aprint_normal("\n"); ! aprint_error("%s: mi_cpu_attach failed with %d\n", ! sc->sc_dev.dv_xname, error); ! return; ! } ! ! /* ! * Note: `eintstack' is set in init_cpuinfo() above. ! * The %wim register will be initialized in cpu_hatch(). ! */ ! cpi->ci_curlwp = cpi->ci_data.cpu_idlelwp; ! cpi->curpcb = (struct pcb *)cpi->ci_curlwp->l_addr; ! cpi->curpcb->pcb_wim = 1; ! ! #else ! sc->sc_cpuinfo = NULL; printf(": no SMP support in kernel\n"); return; - #endif } - - #ifdef DEBUG - cpi->redzone = (void *)((long)cpi->eintstack + REDSIZE); #endif cpi->ci_cpuid = idx; cpi->mid = mid; cpi->node = node; if (sparc_ncpus > 1) { printf(": mid %d", mid); --- 311,336 ---- * (see autoconf.c and cpuunit.c) */ idx = cpu_attach_count++; ! #if !defined(MULTIPROCESSOR) ! if (cpu_attach_count > 1) { printf(": no SMP support in kernel\n"); return; } #endif + /* + * Initialise this cpu's cpu_info. + */ + cpi = sc->sc_cpuinfo = cpus[idx]; + getcpuinfo(cpi, node); + cpi->ci_cpuid = idx; cpi->mid = mid; cpi->node = node; + #ifdef DEBUG + cpi->redzone = (void *)((long)cpi->eintstack + REDSIZE); + #endif if (sparc_ncpus > 1) { printf(": mid %d", mid); *************** cpu_attach(struct cpu_softc *sc, int nod *** 405,428 **** printf(" [WARNING: mid should not be 0]"); } ! if (cpi->master) { ! char buf[100]; ! cpu_setup(); ! snprintf(buf, sizeof buf, "%s @ %s MHz, %s FPU", ! cpi->cpu_name, clockfreq(cpi->hz), cpi->fpu_name); ! snprintf(cpu_model, sizeof cpu_model, "%s (%s)", ! machine_model, buf); ! printf(": %s\n", buf); ! cache_print(sc); return; } ! #if defined(MULTIPROCESSOR) /* for now use the fixed virtual addresses setup in autoconf.c */ cpi->intreg_4m = (struct icr_pi *) ! (PI_INTR_VA + (_MAXNBPG * CPU_MID2CPUNO(mid))); /* Now start this CPU */ cpu_spinup(cpi); --- 338,439 ---- printf(" [WARNING: mid should not be 0]"); } + #if defined(MULTIPROCESSOR) + if (cpu_attach_count > 1) { + cpu_attach_non_boot(sc, cpi, node); + return; + } + #endif /* MULTIPROCESSOR */ + + /* Stuff to only run on the boot CPU */ + cpu_setup(); + snprintf(buf, sizeof buf, "%s @ %s MHz, %s FPU", + cpi->cpu_name, clockfreq(cpi->hz), cpi->fpu_name); + snprintf(cpu_model, sizeof cpu_model, "%s (%s)", + machine_model, buf); + printf(": %s\n", buf); + cache_print(sc); + + cpi->master = 1; + cpi->eintstack = eintstack; + + /* + * If we haven't been able to determine the Id of the + * boot CPU, set it now. In this case we can only boot + * from CPU #0 (see also the CPU attach code in autoconf.c) + */ + if (bootmid == 0) + bootmid = mid; + } + + /* + * Finish CPU attach. + * Must be run by the CPU which is being attached. + */ + void + cpu_setup(void) + { + if (cpuinfo.hotfix) + (*cpuinfo.hotfix)(&cpuinfo); + + /* Initialize FPU */ + fpu_init(&cpuinfo); + + /* Enable the cache */ + cpuinfo.cache_enable(); + + cpuinfo.flags |= CPUFLG_HATCHED; + } + + #if defined(MULTIPROCESSOR) + /* + * Perform most of the tasks needed for a non-boot CPU. + */ + static void + cpu_attach_non_boot(struct cpu_softc *sc, struct cpu_info *cpi, int node) + { + vaddr_t intstack, va; + int error; + + /* + * 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); + if (intstack == 0) + panic("%s: no uspace/intstack", __func__); + cpi->eintstack = (void*)(intstack + INT_STACK_SIZE); ! /* Allocate virtual space for pmap page_copy/page_zero */ ! va = uvm_km_alloc(kernel_map, 2*PAGE_SIZE, 0, UVM_KMF_VAONLY); ! if (va == 0) ! panic("%s: no virtual space", __func__); ! cpi->vpage[0] = (void *)(va + 0); ! cpi->vpage[1] = (void *)(va + PAGE_SIZE); ! ! /* ! * Call the MI attach which creates an idle LWP for us. ! */ ! error = mi_cpu_attach(cpi); ! if (error != 0) { ! aprint_normal("\n"); ! aprint_error("%s: mi_cpu_attach failed with %d\n", ! sc->sc_dev.dv_xname, error); return; } ! /* ! * Note: `eintstack' is set in init_cpuinfo() above. ! * The %wim register will be initialized in cpu_hatch(). ! */ ! cpi->ci_curlwp = cpi->ci_data.cpu_idlelwp; ! cpi->curpcb = (struct pcb *)cpi->ci_curlwp->l_addr; ! cpi->curpcb->pcb_wim = 1; ! /* for now use the fixed virtual addresses setup in autoconf.c */ cpi->intreg_4m = (struct icr_pi *) ! (PI_INTR_VA + (_MAXNBPG * CPU_MID2CPUNO(cpi->mid))); /* Now start this CPU */ cpu_spinup(cpi); *************** cpu_attach(struct cpu_softc *sc, int nod *** 431,437 **** cache_print(sc); ! if (sparc_ncpus > 1 && idx == sparc_ncpus-1) { CPU_INFO_ITERATOR n; /* * Install MP cache flush functions, unless the --- 442,451 ---- cache_print(sc); ! /* ! * Now we're on the last CPU to be attaching. ! */ ! if (sparc_ncpus > 1 && cpi->ci_cpuid == sparc_ncpus - 1) { CPU_INFO_ITERATOR n; /* * Install MP cache flush functions, unless the *************** cpu_attach(struct cpu_softc *sc, int nod *** 446,455 **** SET_CACHE_FUNC(vcache_flush_context); } } ! #endif /* MULTIPROCESSOR */ } - #if defined(MULTIPROCESSOR) /* * Start secondary processors in motion. */ --- 460,468 ---- SET_CACHE_FUNC(vcache_flush_context); } } ! #undef SET_CACHE_FUNC } /* * Start secondary processors in motion. */ *************** cpu_boot_secondary_processors(void) *** 479,519 **** printf("\n"); } - #endif /* MULTIPROCESSOR */ /* ! * Finish CPU attach. ! * Must be run by the CPU which is being attached. */ void ! cpu_setup(void) { - if (cpuinfo.hotfix) - (*cpuinfo.hotfix)(&cpuinfo); - - /* Initialize FPU */ - fpu_init(&cpuinfo); ! /* Enable the cache */ ! cpuinfo.cache_enable(); ! ! cpuinfo.flags |= CPUFLG_HATCHED; } - #if defined(MULTIPROCESSOR) - - extern void cpu_hatch(void); /* in locore.s */ - /* * Allocate per-CPU data, then start up this CPU using PROM. */ void cpu_spinup(struct cpu_info *cpi) { struct openprom_addr oa; ! void *pc = (void *)cpu_hatch; int n; /* Setup CPU-specific MMU tables */ pmap_alloc_cpu(cpi); --- 492,521 ---- printf("\n"); } /* ! * Early initialisation, before main(). */ void ! cpu_init_system(void) { ! mutex_init(&xpmsg_mutex, MUTEX_SPIN, IPL_VM); } /* * Allocate per-CPU data, then start up this CPU using PROM. */ void cpu_spinup(struct cpu_info *cpi) { + extern void cpu_hatch(void); /* in locore.s */ struct openprom_addr oa; ! void *pc; int n; + pc = (void *)cpu_hatch; + /* Setup CPU-specific MMU tables */ pmap_alloc_cpu(cpi); *************** xcall(xcall_func_t func, xcall_trap_t tr *** 556,597 **** u_int cpuset) { struct cpu_info *cpi; ! int s, n, i, done, callself, mybit; volatile struct xpmsg_func *p; int fasttrap; ! ! /* XXX - note p->retval is probably no longer useful */ mybit = (1 << cpuinfo.ci_cpuid); callself = func && (cpuset & mybit) != 0; cpuset &= ~mybit; - /* - * If no cpus are configured yet, just call ourselves. - */ - if (cpus == NULL) { - p = &cpuinfo.msg.u.xpmsg_func; - if (callself) - p->retval = (*func)(arg0, arg1, arg2); - return; - } - /* Mask any CPUs that are not ready */ cpuset &= cpu_ready_mask; /* prevent interrupts that grab the kernel lock */ ! s = splsched(); ! #ifdef DEBUG ! if (!cold) { ! u_int pc, lvl = ((u_int)s & PSR_PIL) >> 8; ! if (lvl > IPL_SCHED) { ! __asm("mov %%i7, %0" : "=r" (pc) : ); ! printf_nolog("%d: xcall at lvl %u from 0x%x\n", ! cpu_number(), lvl, pc); ! } ! } ! #endif ! LOCK_XPMSG(); /* * Firstly, call each CPU. We do this so that they might have --- 558,577 ---- u_int cpuset) { struct cpu_info *cpi; ! int n, i, done, callself, mybit; volatile struct xpmsg_func *p; int fasttrap; ! int is_noop = func == (xcall_func_t)sparc_noop; mybit = (1 << cpuinfo.ci_cpuid); callself = func && (cpuset & mybit) != 0; cpuset &= ~mybit; /* Mask any CPUs that are not ready */ cpuset &= cpu_ready_mask; /* prevent interrupts that grab the kernel lock */ ! mutex_spin_enter(&xpmsg_mutex); /* * Firstly, call each CPU. We do this so that they might have *************** xcall(xcall_func_t func, xcall_trap_t tr *** 621,634 **** */ p = &cpuinfo.msg.u.xpmsg_func; if (callself) ! p->retval = (*func)(arg0, arg1, arg2); /* * Lastly, start looping, waiting for all CPUs to register that they * have completed (bailing if it takes "too long", being loud about * this in the process). */ ! done = 0; i = 100000; /* time-out, not too long, but still an _AGE_ */ while (!done) { if (--i < 0) { --- 601,614 ---- */ p = &cpuinfo.msg.u.xpmsg_func; if (callself) ! (*func)(arg0, arg1, arg2); /* * Lastly, start looping, waiting for all CPUs to register that they * have completed (bailing if it takes "too long", being loud about * this in the process). */ ! done = is_noop; i = 100000; /* time-out, not too long, but still an _AGE_ */ while (!done) { if (--i < 0) { *************** xcall(xcall_func_t func, xcall_trap_t tr *** 654,661 **** if (i < 0) printf_nolog("\n"); ! UNLOCK_XPMSG(); ! splx(s); } /* --- 634,640 ---- if (i < 0) printf_nolog("\n"); ! mutex_spin_exit(&xpmsg_mutex); } /* *************** mp_pause_cpus(void) *** 667,675 **** CPU_INFO_ITERATOR n; struct cpu_info *cpi; - if (cpus == NULL) - return; - for (CPU_INFO_FOREACH(n, cpi)) { if (cpuinfo.mid == cpi->mid || (cpi->flags & CPUFLG_HATCHED) == 0) --- 646,651 ---- *************** mp_resume_cpus(void) *** 694,702 **** CPU_INFO_ITERATOR n; struct cpu_info *cpi; - if (cpus == NULL) - return; - for (CPU_INFO_FOREACH(n, cpi)) { if (cpuinfo.mid == cpi->mid || (cpi->flags & CPUFLG_HATCHED) == 0) --- 670,675 ---- *************** mp_halt_cpus(void) *** 720,728 **** CPU_INFO_ITERATOR n; struct cpu_info *cpi; - if (cpus == NULL) - return; - for (CPU_INFO_FOREACH(n, cpi)) { int r; --- 693,698 ---- *************** mp_pause_cpus_ddb(void) *** 747,755 **** CPU_INFO_ITERATOR n; struct cpu_info *cpi; - if (cpus == NULL) - return; - for (CPU_INFO_FOREACH(n, cpi)) { if (cpi == NULL || cpi->mid == cpuinfo.mid || (cpi->flags & CPUFLG_HATCHED) == 0) --- 717,722 ---- *************** mp_resume_cpus_ddb(void) *** 766,774 **** CPU_INFO_ITERATOR n; struct cpu_info *cpi; - if (cpus == NULL) - return; - for (CPU_INFO_FOREACH(n, cpi)) { if (cpi == NULL || cpuinfo.mid == cpi->mid || (cpi->flags & CPUFLG_PAUSED) == 0) --- 733,738 ---- Index: sys/arch/sparc/sparc/cpuvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpuvar.h,v retrieving revision 1.75.10.2 diff -p -r1.75.10.2 cpuvar.h *** sys/arch/sparc/sparc/cpuvar.h 16 Jan 2011 12:58:23 -0000 1.75.10.2 --- sys/arch/sparc/sparc/cpuvar.h 28 Jan 2011 08:02:23 -0000 *************** *** 37,42 **** --- 37,43 ---- #include "opt_lockdebug.h" #include "opt_ddb.h" #include "opt_sparc_arch.h" + #include "opt_modular.h" #endif #include *************** struct xpmsg { *** 104,115 **** * the trap window (see locore.s). */ struct xpmsg_func { ! int (*func)(int, int, int); void (*trap)(int, int, int); int arg0; int arg1; int arg2; - int retval; } xpmsg_func; } u; volatile int received; --- 105,115 ---- * the trap window (see locore.s). */ struct xpmsg_func { ! void (*func)(int, int, int); void (*trap)(int, int, int); int arg0; int arg1; int arg2; } xpmsg_func; } u; volatile int received; *************** struct xpmsg { *** 117,131 **** }; /* - * This must be locked around all message transactions to ensure only - * one CPU is generating them. - */ - extern struct simplelock xpmsg_lock; - - #define LOCK_XPMSG() simple_lock(&xpmsg_lock); - #define UNLOCK_XPMSG() simple_unlock(&xpmsg_lock); - - /* * The cpuinfo structure. This structure maintains information about one * currently installed CPU (there may be several of these if the machine * supports multiple CPUs, as on some Sun4m architectures). The information --- 117,122 ---- *************** struct cpu_info { *** 415,424 **** #define CPU_INFO_ITERATOR int ! #ifdef MULTIPROCESSOR ! #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 /* --- 406,421 ---- #define CPU_INFO_ITERATOR int ! /* ! * Provide two forms of CPU_INFO_FOREACH. One fast one for non-modular ! * non-SMP kernels, and the other for everyone else. Both work in the ! * non-SMP case, just involving an extra indirection through cpus[0] for ! * the portable version. ! */ ! #if defined(MULTIPROCESSOR) || defined(MODULAR) || defined(_MODULE) ! #define CPU_INFO_FOREACH(cii, cp) cii = 0; (cp = cpus[cii]) && cp->eintstack && cii < sparc_ncpus; cii++ #else ! #define CPU_INFO_FOREACH(cii, cp) (void)cii, cp = curcpu(); cp != NULL; cp = NULL #endif /* *************** void pmap_alloc_cpu (struct cpu_info *); *** 437,443 **** #define CPUSET_ALL 0xffffffffU /* xcall to all configured CPUs */ #if defined(MULTIPROCESSOR) ! typedef int (*xcall_func_t)(int, int, int); typedef void (*xcall_trap_t)(int, int, int); void xcall(xcall_func_t, xcall_trap_t, int, int, int, u_int); /* Shorthand */ --- 434,441 ---- #define CPUSET_ALL 0xffffffffU /* xcall to all configured CPUs */ #if defined(MULTIPROCESSOR) ! void cpu_init_system(void); ! typedef void (*xcall_func_t)(int, int, int); typedef void (*xcall_trap_t)(int, int, int); void xcall(xcall_func_t, xcall_trap_t, int, int, int, u_int); /* Shorthand */ *************** void xcall(xcall_func_t, xcall_trap_t, i *** 472,479 **** extern int bootmid; /* Module ID of boot CPU */ #define CPU_MID2CPUNO(mid) ((mid) != 0 ? (mid) - 8 : 0) - #ifdef MULTIPROCESSOR extern struct cpu_info *cpus[]; extern u_int cpu_ready_mask; /* the set of CPUs marked as READY */ #endif --- 470,477 ---- extern int bootmid; /* Module ID of boot CPU */ #define CPU_MID2CPUNO(mid) ((mid) != 0 ? (mid) - 8 : 0) extern struct cpu_info *cpus[]; + #ifdef MULTIPROCESSOR extern u_int cpu_ready_mask; /* the set of CPUs marked as READY */ #endif Index: sys/arch/sparc/sparc/genassym.cf =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/genassym.cf,v retrieving revision 1.56 diff -p -r1.56 genassym.cf *** sys/arch/sparc/sparc/genassym.cf 20 Sep 2008 18:29:05 -0000 1.56 --- sys/arch/sparc/sparc/genassym.cf 28 Jan 2011 08:02:23 -0000 *************** define V_INTR offsetof(struct uvmexp, i *** 129,134 **** --- 129,135 ---- define V_SOFT offsetof(struct uvmexp, softs) define V_FAULTS offsetof(struct uvmexp, faults) define EV_COUNT offsetof(struct evcnt, ev_count) + define EV_STRUCTSIZE sizeof(struct evcnt) # CPU info structure define CPUINFO_STRUCTSIZE sizeof(struct cpu_info) Index: sys/arch/sparc/sparc/intr.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/intr.c,v retrieving revision 1.100.20.1 diff -p -r1.100.20.1 intr.c *** sys/arch/sparc/sparc/intr.c 30 May 2009 16:57:18 -0000 1.100.20.1 --- sys/arch/sparc/sparc/intr.c 28 Jan 2011 08:02:23 -0000 *************** EVCNT_ATTACH_STATIC(lev13_evcnt); *** 80,85 **** --- 80,118 ---- EVCNT_ATTACH_STATIC(lev14_evcnt); #endif + struct evcnt intrcnt[15] = { + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "spur", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev1", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev2", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev3", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev4", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev5", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev6", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev7", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev8", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev9", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "clock", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev11", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev12", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev13", "hard"), + EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "prof", "hard"), + }; + + EVCNT_ATTACH_STATIC2(intrcnt, 0); + EVCNT_ATTACH_STATIC2(intrcnt, 1); + EVCNT_ATTACH_STATIC2(intrcnt, 2); + EVCNT_ATTACH_STATIC2(intrcnt, 3); + EVCNT_ATTACH_STATIC2(intrcnt, 4); + EVCNT_ATTACH_STATIC2(intrcnt, 5); + EVCNT_ATTACH_STATIC2(intrcnt, 6); + EVCNT_ATTACH_STATIC2(intrcnt, 7); + EVCNT_ATTACH_STATIC2(intrcnt, 8); + EVCNT_ATTACH_STATIC2(intrcnt, 9); + EVCNT_ATTACH_STATIC2(intrcnt, 10); + EVCNT_ATTACH_STATIC2(intrcnt, 11); + EVCNT_ATTACH_STATIC2(intrcnt, 12); + EVCNT_ATTACH_STATIC2(intrcnt, 13); + EVCNT_ATTACH_STATIC2(intrcnt, 14); void strayintr(struct clockframe *); #ifdef DIAGNOSTIC *************** strayintr(struct clockframe *fp) *** 98,106 **** char bits[64]; int timesince; ! printf("stray interrupt ipl 0x%x pc=0x%x npc=0x%x psr=%s\n", ! fp->ipl, fp->pc, fp->npc, bitmask_snprintf(fp->psr, ! PSR_BITS, bits, sizeof(bits))); timesince = time_uptime - straytime; if (timesince <= 10) { --- 131,139 ---- char bits[64]; int timesince; ! printf("stray interrupt cpu%d ipl 0x%x pc=0x%x npc=0x%x psr=%s\n", ! cpu_number(), fp->ipl, fp->pc, fp->npc, ! bitmask_snprintf(fp->psr, PSR_BITS, bits, sizeof(bits))); timesince = time_uptime - straytime; if (timesince <= 10) { *************** xcallintr(void *v) *** 344,350 **** volatile struct xpmsg_func *p = &cpuinfo.msg.u.xpmsg_func; if (p->func) ! p->retval = (*p->func)(p->arg0, p->arg1, p->arg2); break; } } --- 377,383 ---- volatile struct xpmsg_func *p = &cpuinfo.msg.u.xpmsg_func; if (p->func) ! (*p->func)(p->arg0, p->arg1, p->arg2); break; } } Index: sys/arch/sparc/sparc/locore.s =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/locore.s,v retrieving revision 1.244.8.2 diff -p -r1.244.8.2 locore.s *** sys/arch/sparc/sparc/locore.s 16 Jan 2011 12:58:23 -0000 1.244.8.2 --- sys/arch/sparc/sparc/locore.s 28 Jan 2011 08:02:23 -0000 *************** BARF *** 118,123 **** --- 118,132 ---- inc %o1; \ st %o1, [%o0 + %lo(what)] + #if EV_COUNT != 0 + # error "this code does not work with EV_COUNT != 0" + #endif + #if EV_STRUCTSIZE != 32 + # error "this code does not work with EV_STRUCTSIZE != 32" + #else + # define EV_STRUCTSHIFT 5 + #endif + /* * Another handy macro: load one register window, given `base' address. * This can be either a simple register (e.g., %sp) or include an initial *************** softintr_common: *** 2518,2528 **** wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set _C_LABEL(intrcnt), %l4 ! intrcnt[intlev]++; ! ld [%l4 + %l5], %o0 std %l2, [%sp + CCFSZ + 8] ! inc %o0 ! st %o0, [%l4 + %l5] set _C_LABEL(sintrhand), %l4! %l4 = sintrhand[intlev]; ld [%l4 + %l5], %l4 --- 2527,2539 ---- wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set intrcnt, %l4 ! intrcnt[intlev].ev_count++; ! sll %l3, EV_STRUCTSHIFT, %o2 ! ldd [%l4 + %o2], %o0 std %l2, [%sp + CCFSZ + 8] ! inccc %o1 ! addx %o0, 0, %o0 ! std %o0, [%l4 + %o2] set _C_LABEL(sintrhand), %l4! %l4 = sintrhand[intlev]; ld [%l4 + %l5], %l4 *************** sparc_interrupt4m_bogus: *** 2670,2680 **** wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set _C_LABEL(intrcnt), %l4 ! intrcnt[intlev]++; ! ld [%l4 + %l5], %o0 std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe ! inc %o0 ! st %o0, [%l4 + %l5] st %fp, [%sp + CCFSZ + 16] --- 2681,2693 ---- wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set intrcnt, %l4 ! intrcnt[intlev].ev_count++; ! sll %l3, EV_STRUCTSHIFT, %o2 ! ldd [%l4 + %o2], %o0 std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe ! inccc %o1 ! addx %o0, 0, %o0 ! std %o0, [%l4 + %o2] st %fp, [%sp + CCFSZ + 16] *************** sparc_interrupt_common: *** 2715,2725 **** wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set _C_LABEL(intrcnt), %l4 ! intrcnt[intlev]++; ! ld [%l4 + %l5], %o0 std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe ! inc %o0 ! st %o0, [%l4 + %l5] set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev]; ld [%l4 + %l5], %l4 --- 2728,2740 ---- wr %l4, PSR_ET, %psr ! song and dance is necessary std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe sll %l3, 2, %l5 ! set intrcnt, %l4 ! intrcnt[intlev].ev_count++; ! sll %l3, EV_STRUCTSHIFT, %o2 ! ldd [%l4 + %o2], %o0 std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe ! inccc %o1 ! addx %o0, 0, %o0 ! std %o0, [%l4 + %o2] set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev]; ld [%l4 + %l5], %l4 *************** _ENTRY(_C_LABEL(ft_srmmu_vcache_flush_ra *** 2973,2989 **** b ft_rett mov SRMMU_CXR, %l7 ! reload ctx register - _ENTRY(_C_LABEL(ft_want_ast)) - mov 1, %l4 ! ack xcall in all cases - st %l4, [%l6 + CPUINFO_XMSG_CMPLT] ! completed = 1 - - btst PSR_PS, %l0 ! if from user mode - be,a slowtrap ! call trap(T_AST) - mov T_AST, %l3 - - mov %l0, %psr ! else return from trap - nop ! AST will be noticed on out way out - RETT #endif /* MULTIPROCESSOR */ #ifdef notyet --- 2988,2993 ---- *************** zshard: *** 3026,3032 **** */ #if defined(SUN4) ! nmi_sun4: INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) /* --- 3030,3036 ---- */ #if defined(SUN4) ! _ENTRY(_C_LABEL(nmi_sun4)) INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) /* *************** nmi_sun4: *** 3052,3058 **** #endif #if defined(SUN4C) ! nmi_sun4c: INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) /* --- 3056,3062 ---- #endif #if defined(SUN4C) ! _ENTRY(_C_LABEL(nmi_sun4c)) INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) /* *************** nmi_sun4c: *** 3086,3092 **** #endif /* SUN4M */ #endif /* SUN4C */ ! nmi_common: ! and call C code call _C_LABEL(memerr4_4c) ! memerr(0, ser, sva, aer, ava) clr %o0 --- 3090,3096 ---- #endif /* SUN4M */ #endif /* SUN4C */ ! _ENTRY(_C_LABEL(nmi_common)) ! and call C code call _C_LABEL(memerr4_4c) ! memerr(0, ser, sva, aer, ava) clr %o0 *************** nmi_common: *** 3107,3113 **** wr %l4, 0, %y ! restore y #if defined(SUN4M) ! nmi_sun4m: INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) --- 3111,3117 ---- wr %l4, 0, %y ! restore y #if defined(SUN4M) ! _ENTRY(_C_LABEL(nmi_sun4m)) INTR_SETUP(-CCFSZ-80) INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1) *************** _C_LABEL(cpu_hatch): *** 4601,4612 **** wr %g6, 0, %tbr nop; nop; nop ! paranoia ! /* 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 (INT_STACK_SIZE/2) + CCFSZ + 80, %sp sub %o0, %sp, %sp /* Enable traps */ rd %psr, %l0 --- 4605,4629 ---- wr %g6, 0, %tbr nop; nop; nop ! paranoia ! #if 1 set USRSTACK - CCFSZ, %fp ! as if called from user code + + /* Set up a stack. We use the bottom half of the interrupt stack */ sethi %hi(_EINTSTACKP), %o0 ld [%o0 + %lo(_EINTSTACKP)], %o0 set (INT_STACK_SIZE/2) + CCFSZ + 80, %sp sub %o0, %sp, %sp + #else + /* + * Use this CPUs idlelwp's stack + */ + sethi %hi(cpcb), %o0 + ld [%o0 + %lo(cpcb)], %o0 + set USPACE - 80 - CCFSZ, %sp + add %o0, %sp, %sp + + add 80, %sp, %fp + #endif /* Enable traps */ rd %psr, %l0 *************** _C_LABEL(bootinfo): *** 6320,6349 **** _C_LABEL(proc0paddr): .word _C_LABEL(u0) ! KVA of proc0 uarea - /* interrupt counters XXX THESE BELONG ELSEWHERE (if anywhere) */ - .globl _C_LABEL(intrcnt), _C_LABEL(eintrcnt) - .globl _C_LABEL(intrnames), _C_LABEL(eintrnames) - _C_LABEL(intrnames): - .asciz "spur" - .asciz "lev1" - .asciz "lev2" - .asciz "lev3" - .asciz "lev4" - .asciz "lev5" - .asciz "lev6" - .asciz "lev7" - .asciz "lev8" - .asciz "lev9" - .asciz "clock" - .asciz "lev11" - .asciz "lev12" - .asciz "lev13" - .asciz "prof" - _C_LABEL(eintrnames): - _ALIGN - _C_LABEL(intrcnt): - .skip 4*15 - _C_LABEL(eintrcnt): - .comm _C_LABEL(nwindows), 4 .comm _C_LABEL(romp), 4 --- 6337,6341 ---- Index: sys/arch/sparc/sparc/pmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/pmap.c,v retrieving revision 1.322.20.3 diff -p -r1.322.20.3 pmap.c *** sys/arch/sparc/sparc/pmap.c 16 Jan 2011 12:58:23 -0000 1.322.20.3 --- sys/arch/sparc/sparc/pmap.c 28 Jan 2011 08:02:23 -0000 *************** pmap_bootstrap4m(void *top) *** 3505,3510 **** --- 3505,3527 ---- */ p = (vaddr_t)top; + #if defined(MULTIPROCESSOR) + /* + * allocate the rest of the cpu_info{} area. note we waste the + * first one to get a VA space. + */ + cpuinfo_len = ((sizeof(struct cpu_info) + NBPG - 1) & ~PGOFSET); + if (sparc_ncpus > 1) { + p = (p + NBPG - 1) & ~PGOFSET; + cpuinfo_data = (uint8_t *)p; + p += (cpuinfo_len * sparc_ncpus); + + /* XXX we waste the first one */ + memset(cpuinfo_data + cpuinfo_len, 0, cpuinfo_len * (sparc_ncpus - 1)); + } else + cpuinfo_data = (uint8_t *)CPUINFO_VA; + #endif + /* * Intialize the kernel pmap. */ *************** pmap_bootstrap4m(void *top) *** 3542,3563 **** 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 --- 3559,3564 ---- *************** pmap_bootstrap4m(void *top) *** 3802,3817 **** #ifdef MULTIPROCESSOR /* * Remap cpu0 from CPUINFO_VA to the new correct value, wasting the ! * backing pages we allocated above XXX. */ 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); } /* --- 3803,3825 ---- #ifdef MULTIPROCESSOR /* + * Initialise any cpu-specific data now. + */ + cpu_init_system(); + + /* * Remap cpu0 from CPUINFO_VA to the new correct value, wasting the ! * backing page we allocated above XXX. */ for (off = 0, va = (vaddr_t)cpuinfo_data; ! sparc_ncpus > 1 && 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); + cache_flush_page(va, 0); + cache_flush_page(CPUINFO_VA, 0); } /* *************** pmap_bootstrap4m(void *top) *** 3823,3828 **** --- 3831,3838 ---- cpus[i]->ci_self = cpus[i]; prom_printf("set cpu%d ci_self address: %p\n", i, cpus[i]); } + #else + cpus[0] = (struct cpu_info *)CPUINFO_VA; #endif pmap_update(pmap_kernel());