Drop cpuinfo's `L1_ptps'; instead keep a per CPU segment (level 2) page

table descriptor that is used to patch up a region (level 1) page table
associated with a user pmap at context switch time.
This commit is contained in:
pk 1998-10-16 22:39:17 +00:00
parent 759e4c8f58
commit 0bf09a4ae7
4 changed files with 67 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuvar.h,v 1.17 1998/10/12 20:56:48 pk Exp $ */
/* $NetBSD: cpuvar.h,v 1.18 1998/10/16 22:39:18 pk Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -155,6 +155,7 @@ struct cpu_info {
/* Context administration */
int *ctx_tbl; /* [4m] SRMMU-edible context table */
paddr_t ctx_tbl_pa; /* [4m] ctx table physical address */
u_int cpu_seg_ptd; /* [4m] CPUINFO_VA segment ptp PA */
union ctxinfo *ctxinfo;
union ctxinfo *ctx_freelist; /* context free list */
int ctx_kick; /* allocation rover when none free */

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.16 1998/10/12 21:50:22 pk Exp $
# $NetBSD: genassym.cf,v 1.17 1998/10/16 22:39:18 pk Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -132,6 +132,9 @@ define SRUN SRUN
define VM_PMAP offsetof(struct vmspace, vm_map.pmap)
define PMAP_CTX offsetof(struct pmap, pm_ctx)
define PMAP_CTXNUM offsetof(struct pmap, pm_ctxnum)
define PMAP_REGPTPS offsetof(struct pmap, pm_reg_ptps)
define REGTAB_CPU_OFF (int)(&((int *)0)[VA_VREG(CPUINFO_VA)])
# interrupt/fault metering
ifdef UVM
@ -157,6 +160,8 @@ define CPUINFO_REDZONE offsetof(struct cpu_info, redzone)
define REDSIZE REDSIZE
define CPUINFO_IDLE_U offsetof(struct cpu_info, idle_u)
define CPUINFO_CURPCB offsetof(struct cpu_info, curpcb)
define CPUINFO_SEGPTD offsetof(struct cpu_info, cpu_seg_ptd)
define CPUINFO_CPUNO offsetof(struct cpu_info, cpu_no)
# PTE bits and related information
define PG_W PG_W

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.102 1998/10/14 14:47:20 pk Exp $ */
/* $NetBSD: locore.s,v 1.103 1998/10/16 22:39:17 pk Exp $ */
/*
* Copyright (c) 1996 Paul Kranenburg
@ -4841,6 +4841,7 @@ Lsw_load:
/* p does have a context: just switch to it */
Lsw_havectx:
! context is in %o0
! pmap is in %o3
#if (defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
sethi %hi(_cputyp), %o1 ! what cpu are we running on?
ld [%o1 + %lo(_cputyp)], %o1
@ -4865,6 +4866,15 @@ Lsw_havectx:
jmpl %o2, %o7 ! this function must not clobber %o0 and %g7
nop
#if defined(MULTIPROCESSOR)
/* Fixup CPUINFO_VA region table entry */
sethi %hi(CPUINFO_VA+CPUINFO_SEGPTD), %o2
ld [%o2 + %lo(CPUINFO_VA+CPUINFO_SEGPTD)], %o2
ld [%o3 + PMAP_REGPTPS], %o3 ! load region table address
add %o3, REGTAB_CPU_OFF, %o3 ! goto CPUINFO_VA segment entry
st %o2, [%o3] ! switch to this CPU's segment
#endif
set SRMMU_CXR, %o1
jmp %g7 + 8
sta %o0, [%o1] ASI_SRMMU ! setcontext(vm->vm_pmap.pm_ctxnum);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.132 1998/10/08 21:47:34 pk Exp $ */
/* $NetBSD: pmap.c,v 1.133 1998/10/16 22:39:18 pk Exp $ */
/*
* Copyright (c) 1996
@ -1921,15 +1921,27 @@ ctx_alloc(pm)
/* Do any cache flush needed on context switch */
(*cpuinfo.pure_vcache_flush)();
#ifdef DEBUG
#if 0
ctxbusyvector[cnum] = 1; /* mark context as busy */
#endif
if (pm->pm_reg_ptps_pa == 0)
panic("ctx_alloc: no region table in current pmap");
#endif
/*setcontext(0); * paranoia? can we modify curr. ctx? */
#if defined(MULTIPROCESSOR)
for (i = 0; i < ncpu; i++) {
struct cpu_info *cpi = cpus[i];
if (cpi == NULL)
continue;
setpgt4m(&cpi->ctx_tbl[cnum],
(pm->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) |
SRMMU_TEPTD);
}
/* Fixup CPUINFO_VA region table entry for current CPU */
setpgt4m(&pm->pm_reg_ptps[VA_VREG(CPUINFO_VA)],
cpuinfo.cpu_seg_ptd);
#else
setpgt4m(&cpuinfo.ctx_tbl[cnum],
(pm->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
#endif
setcontext4m(cnum);
if (doflush)
@ -3354,12 +3366,10 @@ pmap_bootstrap4m(void)
setpgt4m(&cpuinfo.ctx_tbl[0],
(pmap_kernel()->pm_reg_ptps_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
/* XXX:rethink - Store pointer to region table address */
cpuinfo.L1_ptps = pmap_kernel()->pm_reg_ptps;
for (reg = 0; reg < NKREG; reg++) {
struct regmap *rp;
caddr_t kphyssegtbl;
u_int ptd;
/*
* Entering new region; install & build segtbl
@ -3370,11 +3380,22 @@ pmap_bootstrap4m(void)
kphyssegtbl = (caddr_t)
&kernel_segtable_store[reg * SRMMU_L2SIZE];
ptd = (VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
setpgt4m(&pmap_kernel()->pm_reg_ptps[reg + VA_VREG(KERNBASE)],
(VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
ptd);
rp->rg_seg_ptps = (int *)kphyssegtbl;
if (reg + VA_VREG(KERNBASE) == VA_VREG(CPUINFO_VA)) {
/*
* Store the segment page table descriptor
* corresponding to CPUINFO_VA, so we can install
* this CPU-dependent translation into user pmaps
* at context switch time.
*/
cpuinfo.cpu_seg_ptd = ptd;
}
if (rp->rg_segmap == NULL) {
printf("rp->rg_segmap == NULL!\n");
rp->rg_segmap = &kernel_segmap_store[reg * NSEGRG];
@ -3627,6 +3648,21 @@ pmap_alloc_cpu(sc)
segtable = regtable + SRMMU_L1SIZE;
pagtable = segtable + SRMMU_L2SIZE;
/*
* Store the segment page table descriptor corresponding
* to CPUINFO_VA, so we can install this CPU-dependent
* translation into user pmaps at context switch time.
* Note that the region table we allocate here (`regtable')
* is only used in context 0 on this CPU. Non-zero context
* numbers always have a user pmap associated with it.
* That pmap's region table is fixed up at context switch
* time so that the entry corresponding to CPUINFO_VA points
* at the correct CPU's segment table (and hence the per-CPU
* page table).
*/
sc->cpu_seg_ptd =
(VA2PA((caddr_t)segtable) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD;
vr = VA_VREG(CPUINFO_VA);
vs = VA_VSEG(CPUINFO_VA);
vpg = VA_VPG(CPUINFO_VA);
@ -3655,7 +3691,6 @@ pmap_alloc_cpu(sc)
(SRMMU_TEPTE | PPROT_N_RWX | SRMMU_PG_C));
sc->ctx_tbl = ctxtable;
sc->L1_ptps = regtable;
}
#endif /* SUN4M */
@ -3799,8 +3834,10 @@ pmap_pinit(pm)
/* Copy kernel regions */
for (i = 0; i < NKREG; i++) {
setpgt4m(&pm->pm_reg_ptps[VA_VREG(KERNBASE) + i],
cpuinfo.L1_ptps[VA_VREG(KERNBASE) + i]);
int *kpt, *upt;
kpt = &pmap_kernel()->pm_reg_ptps[VA_VREG(KERNBASE)];
upt = &pm->pm_reg_ptps[VA_VREG(KERNBASE)];
setpgt4m(&upt[i], kpt[i]);
}
}
#endif