version 1.295, 2004/05/01 08:20:11 |
version 1.295.4.1, 2005/04/29 11:28:23 |
Line 128 struct pmap_stats { |
|
Line 128 struct pmap_stats { |
|
int ps_unlink_pvfirst; /* # of pv_unlinks on head */ |
int ps_unlink_pvfirst; /* # of pv_unlinks on head */ |
int ps_unlink_pvsearch; /* # of pv_unlink searches */ |
int ps_unlink_pvsearch; /* # of pv_unlink searches */ |
int ps_changeprots; /* # of calls to changeprot */ |
int ps_changeprots; /* # of calls to changeprot */ |
int ps_useless_changeprots; /* # of changeprots for wiring */ |
|
int ps_enter_firstpv; /* pv heads entered */ |
int ps_enter_firstpv; /* pv heads entered */ |
int ps_enter_secondpv; /* pv nonheads entered */ |
int ps_enter_secondpv; /* pv nonheads entered */ |
int ps_useless_changewire; /* useless wiring changes */ |
int ps_useless_changewire; /* useless wiring changes */ |
Line 923 pgt_page_alloc(struct pool *pp, int flag |
|
Line 922 pgt_page_alloc(struct pool *pp, int flag |
|
return (NULL); |
return (NULL); |
|
|
/* Allocate virtual memory */ |
/* Allocate virtual memory */ |
va = uvm_km_kmemalloc(kmem_map, NULL, PAGE_SIZE, |
va = uvm_km_alloc(kmem_map, PAGE_SIZE, 0, UVM_KMF_VAONLY | |
UVM_KMF_VALLOC | |
|
((flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT | UVM_KMF_TRYLOCK)); |
((flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT | UVM_KMF_TRYLOCK)); |
if (va == 0) { |
if (va == 0) { |
uvm_pagefree(pg); |
uvm_pagefree(pg); |
Line 961 pgt_page_free(struct pool *pp, void *v) |
|
Line 959 pgt_page_free(struct pool *pp, void *v) |
|
KASSERT(rv); |
KASSERT(rv); |
uvm_pagefree(PHYS_TO_VM_PAGE(pa)); |
uvm_pagefree(PHYS_TO_VM_PAGE(pa)); |
pmap_kremove(va, PAGE_SIZE); |
pmap_kremove(va, PAGE_SIZE); |
uvm_km_free(kmem_map, va, PAGE_SIZE); |
uvm_km_free(kmem_map, va, PAGE_SIZE, UVM_KMF_VAONLY); |
} |
} |
#endif /* SUN4M || SUN4D */ |
#endif /* SUN4M || SUN4D */ |
|
|
Line 979 pgt_page_free(struct pool *pp, void *v) |
|
Line 977 pgt_page_free(struct pool *pp, void *v) |
|
#define CTX_USABLE(pm,rp) ((pm)->pm_ctx != NULL ) |
#define CTX_USABLE(pm,rp) ((pm)->pm_ctx != NULL ) |
#endif |
#endif |
|
|
#define GAP_WIDEN(pm,vr) do if (CPU_ISSUN4 || CPU_ISSUN4C) { \ |
#define GAP_WIDEN(pm,vr) do if (CPU_HAS_SUNMMU) { \ |
if (vr + 1 == pm->pm_gap_start) \ |
if (vr + 1 == pm->pm_gap_start) \ |
pm->pm_gap_start = vr; \ |
pm->pm_gap_start = vr; \ |
if (vr == pm->pm_gap_end) \ |
if (vr == pm->pm_gap_end) \ |
pm->pm_gap_end = vr + 1; \ |
pm->pm_gap_end = vr + 1; \ |
} while (0) |
} while (0) |
|
|
#define GAP_SHRINK(pm,vr) do if (CPU_ISSUN4 || CPU_ISSUN4C) { \ |
#define GAP_SHRINK(pm,vr) do if (CPU_HAS_SUNMMU) { \ |
int x; \ |
int x; \ |
x = pm->pm_gap_start + (pm->pm_gap_end - pm->pm_gap_start) / 2; \ |
x = pm->pm_gap_start + (pm->pm_gap_end - pm->pm_gap_start) / 2; \ |
if (vr > x) { \ |
if (vr > x) { \ |
Line 1078 pmap_growkernel(vaddr_t eva) |
|
Line 1076 pmap_growkernel(vaddr_t eva) |
|
return (virtual_end); |
return (virtual_end); |
|
|
/* For now, only implemented for sun4/sun4c */ |
/* For now, only implemented for sun4/sun4c */ |
KASSERT(CPU_ISSUN4 || CPU_ISSUN4C); |
KASSERT(CPU_HAS_SUNMMU); |
|
|
/* |
/* |
* Map in the next region(s) |
* Map in the next region(s) |
|
|
if (pmapdebug & PDB_CTX_ALLOC) |
if (pmapdebug & PDB_CTX_ALLOC) |
printf("ctx_alloc[%d](%p)\n", cpu_number(), pm); |
printf("ctx_alloc[%d](%p)\n", cpu_number(), pm); |
#endif |
#endif |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
gap_start = pm->pm_gap_start; |
gap_start = pm->pm_gap_start; |
gap_end = pm->pm_gap_end; |
gap_end = pm->pm_gap_end; |
} |
} |
|
|
c->c_pmap->pm_ctx = NULL; |
c->c_pmap->pm_ctx = NULL; |
c->c_pmap->pm_ctxnum = 0; |
c->c_pmap->pm_ctxnum = 0; |
doflush = (CACHEINFO.c_vactype != VAC_NONE); |
doflush = (CACHEINFO.c_vactype != VAC_NONE); |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
if (gap_start < c->c_pmap->pm_gap_start) |
if (gap_start < c->c_pmap->pm_gap_start) |
gap_start = c->c_pmap->pm_gap_start; |
gap_start = c->c_pmap->pm_gap_start; |
if (gap_end > c->c_pmap->pm_gap_end) |
if (gap_end > c->c_pmap->pm_gap_end) |
|
|
pm->pm_ctx = c; |
pm->pm_ctx = c; |
pm->pm_ctxnum = cnum; |
pm->pm_ctxnum = cnum; |
|
|
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
|
|
/* |
/* |
* Write pmap's region (3-level MMU) or segment table into |
* Write pmap's region (3-level MMU) or segment table into |
* the MMU. |
* the MMU. |
|
|
pm->pm_ctx = NULL; |
pm->pm_ctx = NULL; |
pm->pm_ctxnum = 0; |
pm->pm_ctxnum = 0; |
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
int octx = getcontext4(); |
int octx = getcontext4(); |
setcontext4(ctx); |
setcontext4(ctx); |
cache_flush_context(ctx); |
cache_flush_context(ctx); |
Line 2987 static void pv_uncache(struct vm_page *p |
|
Line 2986 static void pv_uncache(struct vm_page *p |
|
pv_changepte4m(pg, 0, SRMMU_PG_C); |
pv_changepte4m(pg, 0, SRMMU_PG_C); |
#endif |
#endif |
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
if (CPU_ISSUN4 || CPU_ISSUN4C) |
if (CPU_HAS_SUNMMU) |
pv_changepte4_4c(pg, PG_NC, 0); |
pv_changepte4_4c(pg, PG_NC, 0); |
#endif |
#endif |
simple_unlock(&pg->mdpage.pv_slock); |
simple_unlock(&pg->mdpage.pv_slock); |
Line 3122 pmap_bootstrap(nctx, nregion, nsegment) |
|
Line 3121 pmap_bootstrap(nctx, nregion, nsegment) |
|
#if defined(SUN4M) || defined(SUN4D) |
#if defined(SUN4M) || defined(SUN4D) |
pmap_bootstrap4m(p); |
pmap_bootstrap4m(p); |
#endif |
#endif |
} else if (CPU_ISSUN4 || CPU_ISSUN4C) { |
} else if (CPU_HAS_SUNMMU) { |
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
pmap_bootstrap4_4c(p, nctx, nregion, nsegment); |
pmap_bootstrap4_4c(p, nctx, nregion, nsegment); |
#endif |
#endif |
Line 4019 pmap_alloc_cpu(sc) |
|
Line 4018 pmap_alloc_cpu(sc) |
|
pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist)); |
pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist)); |
|
|
/* Allocate virtual memory */ |
/* Allocate virtual memory */ |
va = uvm_km_valloc(kernel_map, size); |
va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY); |
if (va == 0) |
if (va == 0) |
panic("pmap_alloc_cpu: no memory"); |
panic("pmap_alloc_cpu: no memory"); |
|
|
|
|
} |
} |
#endif /* SUN4M || SUN4D */ |
#endif /* SUN4M || SUN4D */ |
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
sz = NPTESG * sizeof(int); |
sz = NPTESG * sizeof(int); |
pool_init(&pte_pool, sz, 0, 0, 0, "ptemap", NULL); |
pool_init(&pte_pool, sz, 0, 0, 0, "ptemap", NULL); |
} |
} |
Line 4180 pmap_quiet_check(struct pmap *pm) |
|
Line 4179 pmap_quiet_check(struct pmap *pm) |
|
{ |
{ |
int vs, vr; |
int vs, vr; |
|
|
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
#if defined(SUN4_MMU3L) |
#if defined(SUN4_MMU3L) |
if (pm->pm_reglist.tqh_first) |
if (TAILQ_FIRST(&pm->pm_reglist)) |
panic("pmap_destroy: region list not empty"); |
panic("pmap_destroy: region list not empty"); |
#endif |
#endif |
if (pm->pm_seglist.tqh_first) |
if (TAILQ_FIRST(&pm->pm_seglist)) |
panic("pmap_destroy: segment list not empty"); |
panic("pmap_destroy: segment list not empty"); |
} |
} |
|
|
for (vr = 0; vr < NUREG; vr++) { |
for (vr = 0; vr < NUREG; vr++) { |
struct regmap *rp = &pm->pm_regmap[vr]; |
struct regmap *rp = &pm->pm_regmap[vr]; |
|
|
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (HASSUN4_MMU3L) { |
#if defined(SUN4_MMU3L) |
if (rp->rg_smeg != reginval) |
if (HASSUN4_MMU3L) { |
printf("pmap_chk: spurious smeg in " |
if (rp->rg_smeg != reginval) |
"user region %d\n", vr); |
printf("pmap_chk: spurious smeg in " |
|
"user region %d\n", vr); |
|
} |
|
#endif |
|
} |
} |
if (CPU_HAS_SRMMU) { |
if (CPU_HAS_SRMMU) { |
int n; |
int n; |
Line 4230 pmap_quiet_check(struct pmap *pm) |
|
Line 4225 pmap_quiet_check(struct pmap *pm) |
|
printf("pmap_chk: ptes still " |
printf("pmap_chk: ptes still " |
"allocated in segment %d\n", vs); |
"allocated in segment %d\n", vs); |
} |
} |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
if (sp->sg_pmeg != seginval) |
if (sp->sg_pmeg != seginval) |
printf("pmap_chk: pm %p(%d,%d) " |
printf("pmap_chk: pm %p(%d,%d) " |
"spurious soft pmeg %d\n", |
"spurious soft pmeg %d\n", |
Line 4242 pmap_quiet_check(struct pmap *pm) |
|
Line 4237 pmap_quiet_check(struct pmap *pm) |
|
/* Check for spurious pmeg entries in the MMU */ |
/* Check for spurious pmeg entries in the MMU */ |
if (pm->pm_ctx == NULL) |
if (pm->pm_ctx == NULL) |
continue; |
continue; |
if ((CPU_ISSUN4 || CPU_ISSUN4C)) { |
if (CPU_HAS_SUNMMU) { |
int ctx; |
int ctx; |
if (mmu_has_hole && (vr >= 32 || vr < (256 - 32))) |
if (mmu_has_hole && (vr >= 32 || vr < (256 - 32))) |
continue; |
continue; |
Line 4259 pmap_quiet_check(struct pmap *pm) |
|
Line 4254 pmap_quiet_check(struct pmap *pm) |
|
setcontext4(ctx); |
setcontext4(ctx); |
} |
} |
} |
} |
|
if (pm->pm_stats.resident_count) { |
|
printf("pmap_chk: res count %ld\n", |
|
pm->pm_stats.resident_count); |
|
} |
|
if (pm->pm_stats.wired_count) { |
|
printf("pmap_chk: wired count %ld\n", |
|
pm->pm_stats.wired_count); |
|
} |
} |
} |
#endif /* DEBUG */ |
#endif /* DEBUG */ |
|
|
Line 4286 pmap_pmap_pool_ctor(void *arg, void *obj |
|
Line 4289 pmap_pmap_pool_ctor(void *arg, void *obj |
|
/* pm->pm_ctx = NULL; // already done */ |
/* pm->pm_ctx = NULL; // already done */ |
simple_lock_init(&pm->pm_lock); |
simple_lock_init(&pm->pm_lock); |
|
|
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
TAILQ_INIT(&pm->pm_seglist); |
TAILQ_INIT(&pm->pm_seglist); |
#if defined(SUN4_MMU3L) |
#if defined(SUN4_MMU3L) |
TAILQ_INIT(&pm->pm_reglist); |
TAILQ_INIT(&pm->pm_reglist); |
|
|
/* reset active CPU set */ |
/* reset active CPU set */ |
pm->pm_cpuset = 0; |
pm->pm_cpuset = 0; |
#endif |
#endif |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
/* reset the region gap */ |
/* reset the region gap */ |
pm->pm_gap_start = 0; |
pm->pm_gap_start = 0; |
pm->pm_gap_end = VA_VREG(VM_MAXUSER_ADDRESS); |
pm->pm_gap_end = VA_VREG(VM_MAXUSER_ADDRESS); |
Line 4526 static void pgt_lvl23_remove4_4c(struct |
|
Line 4529 static void pgt_lvl23_remove4_4c(struct |
|
/* |
/* |
* SRMMU helper to deallocate level 2 & 3 page tables. |
* SRMMU helper to deallocate level 2 & 3 page tables. |
*/ |
*/ |
static void pgt_lvl23_remove4m(struct pmap *pm, struct regmap *rp, |
static void |
struct segmap *sp, int vr, int vs) |
pgt_lvl23_remove4m(struct pmap *pm, struct regmap *rp, struct segmap *sp, |
|
int vr, int vs) |
{ |
{ |
|
|
/* Invalidate level 2 PTP entry */ |
/* Invalidate level 2 PTP entry */ |
Line 4557 static void pgt_lvl23_remove4m(struct pm |
|
Line 4561 static void pgt_lvl23_remove4m(struct pm |
|
} |
} |
#endif /* SUN4M || SUN4D */ |
#endif /* SUN4M || SUN4D */ |
|
|
void pmap_remove_all(struct pmap *pm) |
void |
|
pmap_remove_all(struct pmap *pm) |
{ |
{ |
if (pm->pm_ctx == NULL) |
if (pm->pm_ctx == NULL) |
return; |
return; |
|
|
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
if (CPU_ISSUN4 || CPU_ISSUN4C) { |
if (CPU_HAS_SUNMMU) { |
int ctx = getcontext4(); |
int ctx = getcontext4(); |
setcontext4(pm->pm_ctxnum); |
setcontext4(pm->pm_ctxnum); |
cache_flush_context(pm->pm_ctxnum); |
cache_flush_context(pm->pm_ctxnum); |
Line 4713 pmap_rmk4_4c(pm, va, endva, vr, vs) |
|
Line 4718 pmap_rmk4_4c(pm, va, endva, vr, vs) |
|
panic("pmap_rmk: too many PTEs in segment; " |
panic("pmap_rmk: too many PTEs in segment; " |
"va 0x%lx; endva 0x%lx", va, endva); |
"va 0x%lx; endva 0x%lx", va, endva); |
#endif |
#endif |
if (pte & PG_WIRED) |
if (pte & PG_WIRED) { |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
|
} |
|
|
if (inmmu) |
if (inmmu) |
setpte4(va, 0); |
setpte4(va, 0); |
Line 4883 pmap_rmu4_4c(pm, va, endva, vr, vs) |
|
Line 4890 pmap_rmu4_4c(pm, va, endva, vr, vs) |
|
if (inmmu) |
if (inmmu) |
setpte4(pteva, 0); |
setpte4(pteva, 0); |
|
|
if (pte & PG_WIRED) |
if (pte & PG_WIRED) { |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
|
} |
*ptep = 0; |
*ptep = 0; |
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
} |
} |
Line 4979 pmap_rmu4m(pm, va, endva, vr, vs) |
|
Line 4988 pmap_rmu4m(pm, va, endva, vr, vs) |
|
setpgt4m_va(va, &pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID, |
setpgt4m_va(va, &pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID, |
pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); |
pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); |
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
|
if (sp->sg_wiremap & (1 << VA_SUN4M_VPG(va))) { |
|
sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); |
|
pm->pm_stats.wired_count--; |
|
} |
} |
} |
|
|
/* |
/* |
Line 5061 pmap_page_protect4_4c(pg, prot) |
|
Line 5074 pmap_page_protect4_4c(pg, prot) |
|
sp->sg_npte = --nleft; |
sp->sg_npte = --nleft; |
ptep = &sp->sg_pte[VA_VPG(va)]; |
ptep = &sp->sg_pte[VA_VPG(va)]; |
|
|
if (*ptep & PG_WIRED) |
if (*ptep & PG_WIRED) { |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
|
} |
|
|
if (sp->sg_pmeg != seginval) { |
if (sp->sg_pmeg != seginval) { |
/* Update PV flags */ |
/* Update PV flags */ |
Line 5259 pmap_changeprot4_4c(pm, va, prot, flags) |
|
Line 5274 pmap_changeprot4_4c(pm, va, prot, flags) |
|
if (pte & PG_WIRED && (flags & PMAP_WIRED) == 0) { |
if (pte & PG_WIRED && (flags & PMAP_WIRED) == 0) { |
pte &= ~PG_WIRED; |
pte &= ~PG_WIRED; |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
} else if ((pte & PG_WIRED) == 0 && flags & PMAP_WIRED) { |
} else if ((pte & PG_WIRED) == 0 && flags & PMAP_WIRED) { |
pte |= PG_WIRED; |
pte |= PG_WIRED; |
sp->sg_nwired++; |
sp->sg_nwired++; |
|
pm->pm_stats.wired_count++; |
} |
} |
pte = (pte & ~PG_PROT) | newprot; |
pte = (pte & ~PG_PROT) | newprot; |
/* Update S/W pte entry */ |
/* Update S/W pte entry */ |
Line 5335 pmap_page_protect4m(pg, prot) |
|
Line 5352 pmap_page_protect4m(pg, prot) |
|
printf("pmap_page_protect[%d](0x%lx, 0x%x)\n", |
printf("pmap_page_protect[%d](0x%lx, 0x%x)\n", |
cpu_number(), VM_PAGE_TO_PHYS(pg), prot); |
cpu_number(), VM_PAGE_TO_PHYS(pg), prot); |
#endif |
#endif |
/* |
|
* Skip unmanaged pages, or operations that do not take |
|
* away write permission. |
|
*/ |
|
if (pg == NULL || prot & VM_PROT_WRITE) |
|
return; |
|
|
|
s = splvm(); |
s = splvm(); |
PMAP_HEAD_TO_MAP_LOCK(); |
PMAP_HEAD_TO_MAP_LOCK(); |
simple_lock(&pg->mdpage.pv_slock); |
simple_lock(&pg->mdpage.pv_slock); |
Line 5393 pmap_page_protect4m(pg, prot) |
|
Line 5403 pmap_page_protect4m(pg, prot) |
|
pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); |
pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); |
|
|
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
|
if (sp->sg_wiremap & (1 << VA_SUN4M_VPG(va))) { |
|
sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); |
|
pm->pm_stats.wired_count--; |
|
} |
|
|
if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) |
if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) |
panic("pmap_page_protect !PG_V: pg %p va %lx", pg, va); |
panic("pmap_page_protect !PG_V: pg %p va %lx", pg, va); |
Line 5526 pmap_changeprot4m(pm, va, prot, flags) |
|
Line 5540 pmap_changeprot4m(pm, va, prot, flags) |
|
int pte, newprot; |
int pte, newprot; |
struct regmap *rp; |
struct regmap *rp; |
struct segmap *sp; |
struct segmap *sp; |
|
boolean_t owired; |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
if (pmapdebug & PDB_CHANGEPROT) |
if (pmapdebug & PDB_CHANGEPROT) |
Line 5541 pmap_changeprot4m(pm, va, prot, flags) |
|
Line 5556 pmap_changeprot4m(pm, va, prot, flags) |
|
sp = &rp->rg_segmap[VA_VSEG(va)]; |
sp = &rp->rg_segmap[VA_VSEG(va)]; |
|
|
pte = sp->sg_pte[VA_SUN4M_VPG(va)]; |
pte = sp->sg_pte[VA_SUN4M_VPG(va)]; |
if ((pte & SRMMU_PROT_MASK) == newprot) { |
owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); |
/* only wiring changed, and we ignore wiring */ |
|
pmap_stats.ps_useless_changeprots++; |
if (owired) { |
return; |
pm->pm_stats.wired_count--; |
|
sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); |
|
} |
|
if (flags & PMAP_WIRED) { |
|
pm->pm_stats.wired_count++; |
|
sp->sg_wiremap |= (1 << VA_SUN4M_VPG(va)); |
} |
} |
|
|
if (pm->pm_ctx) { |
if (pm->pm_ctx) { |
Line 5691 pmap_enk4_4c(pm, va, prot, flags, pg, pt |
|
Line 5711 pmap_enk4_4c(pm, va, prot, flags, pg, pt |
|
*ptep = 0; |
*ptep = 0; |
if (inmmu) |
if (inmmu) |
setpte4(va, 0); |
setpte4(va, 0); |
if (pte & PG_WIRED) |
if (pte & PG_WIRED) { |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
|
} |
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
} else { |
} else { |
/* adding new entry */ |
/* adding new entry */ |
Line 5722 pmap_enk4_4c(pm, va, prot, flags, pg, pt |
|
Line 5744 pmap_enk4_4c(pm, va, prot, flags, pg, pt |
|
|
|
/* Update S/W page table */ |
/* Update S/W page table */ |
*ptep = pteproto; |
*ptep = pteproto; |
if (pteproto & PG_WIRED) |
if (pteproto & PG_WIRED) { |
sp->sg_nwired++; |
sp->sg_nwired++; |
|
pm->pm_stats.wired_count++; |
|
} |
pm->pm_stats.resident_count++; |
pm->pm_stats.resident_count++; |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
Line 5846 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
Line 5870 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
if ((pte & (PG_PFNUM|PG_TYPE)) == |
if ((pte & (PG_PFNUM|PG_TYPE)) == |
(pteproto & (PG_PFNUM|PG_TYPE))) { |
(pteproto & (PG_PFNUM|PG_TYPE))) { |
/* just changing prot and/or wiring */ |
/* just changing prot and/or wiring */ |
/* caller should call this directly: */ |
|
pmap_changeprot4_4c(pm, va, prot, flags); |
pmap_changeprot4_4c(pm, va, prot, flags); |
if ((flags & PMAP_WIRED) != 0) |
|
pm->pm_stats.wired_count++; |
|
else |
|
pm->pm_stats.wired_count--; |
|
splx(s); |
splx(s); |
return (0); |
return (0); |
} |
} |
Line 5884 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
Line 5903 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
cache_flush_page(va, pm->pm_ctxnum); |
cache_flush_page(va, pm->pm_ctxnum); |
} |
} |
} |
} |
if (pte & PG_WIRED) |
if (pte & PG_WIRED) { |
sp->sg_nwired--; |
sp->sg_nwired--; |
|
pm->pm_stats.wired_count--; |
|
} |
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
ptep[VA_VPG(va)] = 0; |
ptep[VA_VPG(va)] = 0; |
if (sp->sg_pmeg != seginval) |
if (sp->sg_pmeg != seginval) |
Line 5893 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
Line 5914 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
} else { |
} else { |
/* adding new entry */ |
/* adding new entry */ |
sp->sg_npte++; |
sp->sg_npte++; |
|
|
/* |
|
* Increment counters |
|
*/ |
|
if ((flags & PMAP_WIRED) != 0) |
|
pm->pm_stats.wired_count++; |
|
} |
} |
} |
} |
|
|
Line 5915 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
Line 5930 pmap_enu4_4c(pm, va, prot, flags, pg, pt |
|
/* Update S/W page table */ |
/* Update S/W page table */ |
ptep += VA_VPG(va); |
ptep += VA_VPG(va); |
*ptep = pteproto; |
*ptep = pteproto; |
if (pteproto & PG_WIRED) |
if (pteproto & PG_WIRED) { |
sp->sg_nwired++; |
sp->sg_nwired++; |
|
pm->pm_stats.wired_count++; |
|
} |
pm->pm_stats.resident_count++; |
pm->pm_stats.resident_count++; |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
Line 6025 pmap_lockmmu(vaddr_t sva, size_t sz) |
|
Line 6042 pmap_lockmmu(vaddr_t sva, size_t sz) |
|
struct segmap *sp; |
struct segmap *sp; |
int vr, vs; |
int vr, vs; |
|
|
if (CPU_ISSUN4M || CPU_ISSUN4D) |
if (CPU_HAS_SRMMU) |
return; |
return; |
|
|
eva = sva + sz; |
eva = sva + sz; |
Line 6363 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
Line 6380 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
int error = 0; |
int error = 0; |
struct regmap *rp; |
struct regmap *rp; |
struct segmap *sp; |
struct segmap *sp; |
|
boolean_t owired; |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
if (KERNBASE < va) |
if (KERNBASE < va) |
Line 6436 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
Line 6454 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
|
|
sp = &rp->rg_segmap[vs]; |
sp = &rp->rg_segmap[vs]; |
|
|
|
owired = FALSE; |
if ((pte = sp->sg_pte) == NULL) { |
if ((pte = sp->sg_pte) == NULL) { |
/* definitely a new mapping */ |
/* definitely a new mapping */ |
int i; |
int i; |
Line 6475 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
Line 6494 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
/* just changing prot and/or wiring */ |
/* just changing prot and/or wiring */ |
/* caller should call this directly: */ |
/* caller should call this directly: */ |
pmap_changeprot4m(pm, va, prot, flags); |
pmap_changeprot4m(pm, va, prot, flags); |
if ((flags & PMAP_WIRED) != 0) |
|
pm->pm_stats.wired_count++; |
|
else |
|
pm->pm_stats.wired_count--; |
|
simple_unlock(&pm->pm_lock); |
simple_unlock(&pm->pm_lock); |
PMAP_MAP_TO_HEAD_UNLOCK(); |
PMAP_MAP_TO_HEAD_UNLOCK(); |
splx(s); |
splx(s); |
Line 6517 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
Line 6532 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
SRMMU_TEINVALID, pm->pm_ctx != NULL, |
SRMMU_TEINVALID, pm->pm_ctx != NULL, |
pm->pm_ctxnum, PMAP_CPUSET(pm)); |
pm->pm_ctxnum, PMAP_CPUSET(pm)); |
pm->pm_stats.resident_count--; |
pm->pm_stats.resident_count--; |
|
owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); |
} else { |
} else { |
/* adding new entry */ |
/* adding new entry */ |
sp->sg_npte++; |
sp->sg_npte++; |
|
|
/* |
|
* Increment counters |
|
*/ |
|
if ((flags & PMAP_WIRED) != 0) |
|
pm->pm_stats.wired_count++; |
|
} |
} |
} |
} |
|
|
Line 6544 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
Line 6554 pmap_enu4m(pm, va, prot, flags, pg, ptep |
|
*/ |
*/ |
setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto); |
setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto); |
pm->pm_stats.resident_count++; |
pm->pm_stats.resident_count++; |
|
if (owired) { |
|
pm->pm_stats.wired_count--; |
|
sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); |
|
} |
|
if (flags & PMAP_WIRED) { |
|
pm->pm_stats.wired_count++; |
|
sp->sg_wiremap |= (1 << VA_SUN4M_VPG(va)); |
|
} |
|
|
out: |
out: |
simple_unlock(&pm->pm_lock); |
simple_unlock(&pm->pm_lock); |
Line 6696 pmap_unwire(pm, va) |
|
Line 6714 pmap_unwire(pm, va) |
|
struct pmap *pm; |
struct pmap *pm; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
int vr, vs, pte, *ptep; |
int vr, vs, *ptep; |
struct regmap *rp; |
struct regmap *rp; |
struct segmap *sp; |
struct segmap *sp; |
|
boolean_t owired; |
/* For now, `wired page accounting' is only used on sun4/sun4c */ |
|
if (CPU_HAS_SRMMU) |
|
return; |
|
|
|
vr = VA_VREG(va); |
vr = VA_VREG(va); |
vs = VA_VSEG(va); |
vs = VA_VSEG(va); |
rp = &pm->pm_regmap[vr]; |
rp = &pm->pm_regmap[vr]; |
sp = &rp->rg_segmap[vs]; |
sp = &rp->rg_segmap[vs]; |
ptep = &sp->sg_pte[VA_VPG(va)]; |
|
pte = *ptep; |
|
|
|
#if defined(SUN4) || defined(SUN4C) |
owired = FALSE; |
if ((pte & PG_WIRED) == 0) { |
if (CPU_HAS_SUNMMU) { |
|
ptep = &sp->sg_pte[VA_VPG(va)]; |
|
owired = *ptep & PG_WIRED; |
|
*ptep &= ~PG_WIRED; |
|
} |
|
if (CPU_HAS_SRMMU) { |
|
owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); |
|
sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); |
|
} |
|
if (!owired) { |
pmap_stats.ps_useless_changewire++; |
pmap_stats.ps_useless_changewire++; |
return; |
return; |
} |
} |
|
|
pte &= ~PG_WIRED; |
pm->pm_stats.wired_count--; |
*ptep = pte; |
#if defined(SUN4) || defined(SUN4C) |
if (--sp->sg_nwired <= 0) { |
if (CPU_HAS_SUNMMU && --sp->sg_nwired <= 0) { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) |
if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) |
panic("pmap_unwire: pm %p, va %lx: nleft=%d, nwired=%d", |
panic("pmap_unwire: pm %p, va %lx: nleft=%d, nwired=%d", |
Line 6728 pmap_unwire(pm, va) |
|
Line 6750 pmap_unwire(pm, va) |
|
if (sp->sg_pmeg != seginval) |
if (sp->sg_pmeg != seginval) |
mmu_pmeg_unlock(sp->sg_pmeg); |
mmu_pmeg_unlock(sp->sg_pmeg); |
} |
} |
#endif |
#endif /* SUN4 || SUN4C */ |
} |
} |
|
|
/* |
/* |
Line 7746 pmap_dumpsize() |
|
Line 7768 pmap_dumpsize() |
|
sz += npmemarr * sizeof(phys_ram_seg_t); |
sz += npmemarr * sizeof(phys_ram_seg_t); |
sz += sizeof(kernel_segmap_store); |
sz += sizeof(kernel_segmap_store); |
|
|
if (CPU_ISSUN4 || CPU_ISSUN4C) |
if (CPU_HAS_SUNMMU) |
/* For each pmeg in the MMU, we'll write NPTESG PTEs. */ |
/* For each pmeg in the MMU, we'll write NPTESG PTEs. */ |
sz += (seginval + 1) * NPTESG * sizeof(int); |
sz += (seginval + 1) * NPTESG * sizeof(int); |
|
|
Line 7817 pmap_dumpmmu(dump, blkno) |
|
Line 7839 pmap_dumpmmu(dump, blkno) |
|
kcpup->segmapoffset = segmapoffset = |
kcpup->segmapoffset = segmapoffset = |
memsegoffset + npmemarr * sizeof(phys_ram_seg_t); |
memsegoffset + npmemarr * sizeof(phys_ram_seg_t); |
|
|
kcpup->npmeg = (CPU_ISSUN4 || CPU_ISSUN4C) ? seginval + 1 : 0; |
kcpup->npmeg = (CPU_HAS_SUNMMU) ? seginval + 1 : 0; |
kcpup->pmegoffset = pmegoffset = |
kcpup->pmegoffset = pmegoffset = |
segmapoffset + kcpup->nsegmap * sizeof(struct segmap); |
segmapoffset + kcpup->nsegmap * sizeof(struct segmap); |
|
|
Line 8144 int pmap_dump(struct pmap *pm) |
|
Line 8166 int pmap_dump(struct pmap *pm) |
|
continue; |
continue; |
} |
} |
for (n = 0, i = 0; i < NPTESG; i++) { |
for (n = 0, i = 0; i < NPTESG; i++) { |
if (sp->sg_pte[i] & PG_WIRED) |
if (CPU_HAS_SUNMMU && sp->sg_pte[i] & PG_WIRED) |
|
n++; |
|
if (CPU_HAS_SRMMU && sp->sg_wiremap & (1 << i)) |
n++; |
n++; |
} |
} |
if (n != sp->sg_nwired) |
if (n != sp->sg_nwired) |