Port-sparc archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
re: partially working SMP again
> > Ok, so why not just ensure that you never access your own map
> > through the shared VA ?
>
> Well, not that easy either - lots of asm code just uses the shared VA,
> while C code (via curcpu()) uses the global VA.
I wonder which is easier to rewrite all shared VA asm references
or to hassle with special VA mappings on earlier bootstrap
with /boot support..
there are hundreds of references to fix. i'd like to get there
eventually, but for now...the patch below seems to get things
setup the right way.
i still haven't gotten CPU1 to run userland though...and if i
enable the new %sp setting code in cpu_hatch, ddb is not able
to pause CPU1 when breaking into the debugger.
.mrg.
Index: sparc/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v
retrieving revision 1.216
diff -p -r1.216 cpu.c
*** sparc/cpu.c 30 May 2009 01:19:29 -0000 1.216
--- sparc/cpu.c 30 May 2009 02:46:30 -0000
*************** getcacheinfo_obp(struct cpu_info *sc, in
*** 1123,1128 ****
--- 1123,1157 ----
struct cacheinfo *ci = &sc->cacheinfo;
int i, l;
+ #if defined(MULTIPROCESSOR)
+ /*
+ * We really really want the cache info early for MP systems,
+ * so figure out the boot node, if we can.
+ *
+ * XXX this loop stolen from mainbus_attach()
+ */
+ if (node == 0 && CPU_ISSUN4M && bootmid != 0) {
+ const char *cp;
+ char namebuf[32];
+ int mid, node2;
+
+ for (node2 = firstchild(findroot());
+ node2;
+ node2 = nextsibling(node2)) {
+ cp = prom_getpropstringA(node2, "device_type",
+ namebuf, sizeof namebuf);
+ if (strcmp(cp, "cpu") != 0)
+ continue;
+
+ mid = prom_getpropint(node2, "mid", -1);
+ if (mid == bootmid) {
+ node = node2;
+ break;
+ }
+ }
+ }
+ #endif
+
if (node == 0)
/* Bootstrapping */
return;
*************** getcpuinfo(struct cpu_info *sc, int node
*** 1862,1867 ****
--- 1891,1899 ----
if (sc->cacheinfo.c_vactype == VAC_UNKNOWN)
sc->cacheinfo.c_vactype = mp->minfo->vactype;
+ if (sc->master && mp->minfo->getmid != NULL)
+ bootmid = mp->minfo->getmid();
+
mp->minfo->getcacheinfo(sc, node);
if (node && sc->hz == 0 && !CPU_ISSUN4/*XXX*/) {
*************** getcpuinfo(struct cpu_info *sc, int node
*** 1875,1883 ****
}
}
- if (sc->master && mp->minfo->getmid != NULL)
- bootmid = mp->minfo->getmid();
-
/*
* Copy CPU/MMU/Cache specific routines into cpu_info.
*/
--- 1907,1912 ----
Index: sparc/cpuvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpuvar.h,v
retrieving revision 1.78
diff -p -r1.78 cpuvar.h
*** sparc/cpuvar.h 27 May 2009 02:19:49 -0000 1.78
--- sparc/cpuvar.h 30 May 2009 02:46:30 -0000
*************** struct cpu_info {
*** 325,330 ****
--- 325,336 ----
/*bus_space_handle_t*/ long ci_mxccregs;
u_int ci_tt; /* Last trap (if tracing) */
+
+ /*
+ * Start/End VA's of this cpu_info region; we upload the other pages
+ * in this region that aren't part of the cpu_info to uvm.
+ */
+ vaddr_t ci_free_sva1, ci_free_eva1, ci_free_sva2, ci_free_eva2;
};
/*
Index: sparc/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/intr.c,v
retrieving revision 1.104
diff -p -r1.104 intr.c
*** sparc/intr.c 27 May 2009 02:19:50 -0000 1.104
--- sparc/intr.c 30 May 2009 02:46:30 -0000
*************** void bogusintr(struct clockframe *);
*** 94,99 ****
--- 94,100 ----
void
strayintr(struct clockframe *fp)
{
+ #if 0
static int straytime, nstray;
char bits[64];
int timesince;
*************** strayintr(struct clockframe *fp)
*** 110,115 ****
--- 111,117 ----
straytime = time_uptime;
nstray = 1;
}
+ #endif
}
Index: sparc/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/locore.s,v
retrieving revision 1.246
diff -p -r1.246 locore.s
*** sparc/locore.s 29 May 2009 22:06:55 -0000 1.246
--- sparc/locore.s 30 May 2009 02:46:30 -0000
*************** _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
--- 4601,4623 ----
wr %g6, 0, %tbr
nop; nop; nop ! paranoia
set USRSTACK - CCFSZ, %fp ! as if called from user code
+
+ #if 1
+ /* 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
+ #endif
/* Enable traps */
rd %psr, %l0
Index: sparc/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/pmap.c,v
retrieving revision 1.329
diff -p -r1.329 pmap.c
*** sparc/pmap.c 27 May 2009 02:19:50 -0000 1.329
--- sparc/pmap.c 30 May 2009 02:46:30 -0000
*************** pmap_page_upload(void)
*** 1148,1153 ****
--- 1148,1175 ----
atop(start),
atop(end), VM_FREELIST_DEFAULT);
}
+
+ #if defined(MULTIPROCESSOR)
+ {
+ CPU_INFO_ITERATOR cpunum;
+ struct cpu_info *cpi;
+
+ for (CPU_INFO_FOREACH(cpunum, cpi)) {
+ if (cpi->ci_free_sva1)
+
uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)),
+ VM_FREELIST_DEFAULT);
+ if (cpi->ci_free_sva2)
+
uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)),
+
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)),
+ VM_FREELIST_DEFAULT);
+ }
+ }
+ #endif
}
/*
*************** pmap_bootstrap4m(void *top)
*** 3467,3474 ****
vaddr_t va;
#ifdef MULTIPROCESSOR
vsize_t off;
! size_t cpuinfo_len;
uint8_t *cpuinfo_data;
#endif
/*
--- 3489,3499 ----
vaddr_t va;
#ifdef MULTIPROCESSOR
vsize_t off;
! size_t cpuinfo_len = sizeof(struct cpu_info);
uint8_t *cpuinfo_data;
+ int align = PAGE_SIZE;
+ vaddr_t sva, cpuinfo_va;
+ vsize_t sz;
#endif
/*
*************** pmap_bootstrap4m(void *top)
*** 3502,3520 ****
*/
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
--- 3527,3559 ----
*/
p = (vaddr_t)top;
+ p = (p + NBPG - 1) & ~PGOFSET;
+
#if defined(MULTIPROCESSOR)
/*
! * Allocate aligned KVA. `cpuinfo' resides at a fixed virtual
! * address. Since we need to access an other CPU's cpuinfo
! * structure occasionally, this must be done at a virtual address
! * that's cache congruent to the fixed address CPUINFO_VA.
! *
! * NOTE: we're using the cache properties of the boot CPU to
! * determine the alignment (XXX).
*/
if (sparc_ncpus > 1) {
! if (CACHEINFO.c_totalsize > align) {
! /* Need a power of two */
! while (align <= CACHEINFO.c_totalsize)
! align <<= 1;
! align >>= 1;
! }
! sz = sizeof(struct cpu_info);
!
! sz = (sz + PAGE_SIZE - 1) & -PAGE_SIZE;
! cpuinfo_len = sz + align - PAGE_SIZE;
!
! /* Grab as much space as we need */
cpuinfo_data = (uint8_t *)p;
p += (cpuinfo_len * sparc_ncpus);
} else
cpuinfo_data = (uint8_t *)CPUINFO_VA;
#endif
*************** pmap_bootstrap4m(void *top)
*** 3798,3832 ****
*/
mmu_install_tables(&cpuinfo);
! #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);
- }
-
- /*
* Setup the cpus[] array and the ci_self links.
*/
prom_printf("setting cpus self reference\n");
for (i = 0; i < sparc_ncpus; i++) {
! 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]);
}
#else
cpus[0] = (struct cpu_info *)CPUINFO_VA;
--- 3837,3899 ----
*/
mmu_install_tables(&cpuinfo);
! #if defined(MULTIPROCESSOR)
/*
* Initialise any cpu-specific data now.
*/
cpu_init_system();
/*
* Setup the cpus[] array and the ci_self links.
*/
prom_printf("setting cpus self reference\n");
for (i = 0; i < sparc_ncpus; i++) {
! sva = (vaddr_t) (cpuinfo_data + (cpuinfo_len * i));
! cpuinfo_va = sva +
! (((CPUINFO_VA & (align - 1)) + align - sva) & (align - 1));
!
! /*
! * Either remap from CPUINFO_VA to the new correct value
! * or clear out this cpuinfo.
! */
! if (i == 0) {
! for (off = 0, va = cpuinfo_va;
! 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);
! }
!
! } else
! memset((void *)cpuinfo_va, 0, sizeof(struct cpu_info));
!
! cpus[i] = (struct cpu_info *)cpuinfo_va;
cpus[i]->ci_self = cpus[i];
prom_printf("set cpu%d ci_self address: %p\n", i, cpus[i]);
+
+ /* Unmap and prepare to return unused pages */
+ if (cpuinfo_va != sva) {
+ cpus[i]->ci_free_sva1 = sva;
+ cpus[i]->ci_free_eva1 = cpuinfo_va;
+ for (va = cpus[i]->ci_free_sva1;
+ va < cpus[i]->ci_free_eva1;
+ va += NBPG)
+ setpte4m(va, 0);
+ }
+ if (cpuinfo_va + sz != sva + cpuinfo_len) {
+ cpus[i]->ci_free_sva2 = cpuinfo_va + sz;
+ cpus[i]->ci_free_eva2 = sva + cpuinfo_len;
+ for (va = cpus[i]->ci_free_sva2;
+ va < cpus[i]->ci_free_eva2;
+ va += NBPG)
+ setpte4m(va, 0);
+ }
}
#else
cpus[0] = (struct cpu_info *)CPUINFO_VA;
Home |
Main Index |
Thread Index |
Old Index