Module Name: src
Committed By: mrg
Date: Mon May 18 01:36:11 UTC 2009
Modified Files:
src/sys/arch/sparc/sparc: cpu.c cpuvar.h db_interface.c locore.s pmap.c
Log Message:
- 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.
To generate a diff of this commit:
cvs rdiff -u -r1.213 -r1.214 src/sys/arch/sparc/sparc/cpu.c
cvs rdiff -u -r1.76 -r1.77 src/sys/arch/sparc/sparc/cpuvar.h
cvs rdiff -u -r1.83 -r1.84 src/sys/arch/sparc/sparc/db_interface.c
cvs rdiff -u -r1.244 -r1.245 src/sys/arch/sparc/sparc/locore.s
cvs rdiff -u -r1.326 -r1.327 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.213 src/sys/arch/sparc/sparc/cpu.c:1.214
--- src/sys/arch/sparc/sparc/cpu.c:1.213 Tue Mar 10 23:58:20 2009
+++ src/sys/arch/sparc/sparc/cpu.c Mon May 18 01:36:11 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.213 2009/03/10 23:58:20 martin Exp $ */
+/* $NetBSD: cpu.c,v 1.214 2009/05/18 01:36:11 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.213 2009/03/10 23:58:20 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.214 2009/05/18 01:36:11 mrg 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.76 src/sys/arch/sparc/sparc/cpuvar.h:1.77
--- src/sys/arch/sparc/sparc/cpuvar.h:1.76 Tue Mar 10 23:58:20 2009
+++ src/sys/arch/sparc/sparc/cpuvar.h Mon May 18 01:36:11 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuvar.h,v 1.76 2009/03/10 23:58:20 martin Exp $ */
+/* $NetBSD: cpuvar.h,v 1.77 2009/05/18 01:36:11 mrg 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.83 src/sys/arch/sparc/sparc/db_interface.c:1.84
--- src/sys/arch/sparc/sparc/db_interface.c:1.83 Tue Mar 10 23:58:20 2009
+++ src/sys/arch/sparc/sparc/db_interface.c Mon May 18 01:36:11 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.83 2009/03/10 23:58:20 martin Exp $ */
+/* $NetBSD: db_interface.c,v 1.84 2009/05/18 01:36:11 mrg Exp $ */
/*
* Mach Operating System
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.83 2009/03/10 23:58:20 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.84 2009/05/18 01:36:11 mrg 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 src/sys/arch/sparc/sparc/locore.s:1.245
--- src/sys/arch/sparc/sparc/locore.s:1.244 Sun May 25 15:56:12 2008
+++ src/sys/arch/sparc/sparc/locore.s Mon May 18 01:36:11 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.244 2008/05/25 15:56:12 chs Exp $ */
+/* $NetBSD: locore.s,v 1.245 2009/05/18 01:36:11 mrg 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.326 src/sys/arch/sparc/sparc/pmap.c:1.327
--- src/sys/arch/sparc/sparc/pmap.c:1.326 Wed Mar 18 16:00:14 2009
+++ src/sys/arch/sparc/sparc/pmap.c Mon May 18 01:36:11 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.326 2009/03/18 16:00:14 cegger Exp $ */
+/* $NetBSD: pmap.c,v 1.327 2009/05/18 01:36:11 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.326 2009/03/18 16:00:14 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.327 2009/05/18 01:36:11 mrg Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -3467,7 +3467,8 @@
vaddr_t va;
#ifdef MULTIPROCESSOR
vsize_t off;
- struct vm_page *pg;
+ size_t cpuinfo_len;
+ uint8_t *cpuinfo_data;
#endif
/*
@@ -3538,6 +3539,22 @@
p += ncontext * sizeof *ci;
memset((void *)ci, 0, (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
@@ -3781,62 +3798,31 @@
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_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;
@@ -4448,7 +4434,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);
@@ -6285,7 +6271,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],