Index: sparc64/include/tte.h =================================================================== RCS file: /home/ncvs/src/sys/sparc64/include/tte.h,v retrieving revision 1.15 diff -u -r1.15 tte.h --- sparc64/include/tte.h 29 Dec 2002 08:37:11 -0000 1.15 +++ sparc64/include/tte.h 8 Feb 2003 19:58:38 -0000 @@ -68,6 +68,8 @@ #define TD_NFO (1UL << 60) #define TD_IE (1UL << 59) #define TD_PA(pa) ((pa) & (TD_PA_MASK << TD_PA_SHIFT)) +/* NOTE: bit 6 of TD_SOFT will be sign-extended if used as an immediate. */ +#define TD_FAKE ((1UL << 5) << TD_SOFT_SHIFT) #define TD_EXEC ((1UL << 4) << TD_SOFT_SHIFT) #define TD_REF ((1UL << 3) << TD_SOFT_SHIFT) #define TD_PV ((1UL << 2) << TD_SOFT_SHIFT) Index: sparc64/sparc64/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/pmap.c,v retrieving revision 1.100 diff -u -r1.100 pmap.c --- sparc64/sparc64/pmap.c 5 Jan 2003 05:30:40 -0000 1.100 +++ sparc64/sparc64/pmap.c 8 Feb 2003 20:09:18 -0000 @@ -663,6 +663,8 @@ struct tte *tp; int color; + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_cache_enter: fake page")); PMAP_STATS_INC(pmap_ncache_enter); /* @@ -734,6 +736,8 @@ CTR3(KTR_PMAP, "pmap_cache_remove: m=%p va=%#lx c=%d", m, va, m->md.colors[DCACHE_COLOR(va)]); + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_cache_remove: fake page")); KASSERT(m->md.colors[DCACHE_COLOR(va)] > 0, ("pmap_cache_remove: no mappings %d <= 0", m->md.colors[DCACHE_COLOR(va)])); @@ -1245,20 +1249,22 @@ u_long data; data = atomic_readandclear_long(&tp->tte_data); - m = PHYS_TO_VM_PAGE(TD_PA(data)); - TAILQ_REMOVE(&m->md.tte_list, tp, tte_link); - if ((data & TD_WIRED) != 0) - pm->pm_stats.wired_count--; - if ((data & TD_PV) != 0) { - if ((data & TD_W) != 0 && pmap_track_modified(pm, va)) - vm_page_dirty(m); - if ((data & TD_REF) != 0) - vm_page_flag_set(m, PG_REFERENCED); - if (TAILQ_EMPTY(&m->md.tte_list)) - vm_page_flag_clear(m, PG_WRITEABLE); - pm->pm_stats.resident_count--; + if ((data & TD_FAKE) == 0) { + m = PHYS_TO_VM_PAGE(TD_PA(data)); + TAILQ_REMOVE(&m->md.tte_list, tp, tte_link); + if ((data & TD_WIRED) != 0) + pm->pm_stats.wired_count--; + if ((data & TD_PV) != 0) { + if ((data & TD_W) != 0 && pmap_track_modified(pm, va)) + vm_page_dirty(m); + if ((data & TD_REF) != 0) + vm_page_flag_set(m, PG_REFERENCED); + if (TAILQ_EMPTY(&m->md.tte_list)) + vm_page_flag_clear(m, PG_WRITEABLE); + pm->pm_stats.resident_count--; + } + pmap_cache_remove(m, va); } - pmap_cache_remove(m, va); TTE_ZERO(tp); if (PMAP_REMOVE_DONE(pm)) return (0); @@ -1301,7 +1307,7 @@ vm_offset_t va; KASSERT((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0, - ("pv_remove_all: illegal for unmanaged page %#lx", + ("pmap_remove_all: illegal for unmanaged/fake page %#lx", VM_PAGE_TO_PHYS(m))); for (tp = TAILQ_FIRST(&m->md.tte_list); tp != NULL; tp = tpn) { tpn = TAILQ_NEXT(tp, tte_link); @@ -1391,6 +1397,20 @@ PMAP_STATS_INC(pmap_nenter); pa = VM_PAGE_TO_PHYS(m); + /* + * XXX: convert fictitious pages that cover kernel memory to the real + * page. If the mapping is read only we could just mark the tte as + * fake and map uncacheable, but this may allow illegal aliases into + * the data cache. While this may be harmless, the rest of the code + * assumes that there will never be an illegal alias so play it safe. + * Fictitious pages that correspond to device memory are just marked + * fake, and mapped physically and virtual uncacheable, and with the + * side effect bit set. + */ + if ((m->flags & PG_FICTITIOUS) != 0 && + (pa >= avail_start && pa <= avail_end)) + m = PHYS_TO_VM_PAGE(pa); + CTR6(KTR_PMAP, "pmap_enter: ctx=%p m=%p va=%#lx pa=%#lx prot=%#x wired=%d", pm->pm_context[PCPU_GET(cpuid)], m, va, pa, prot, wired); @@ -1472,7 +1492,7 @@ /* * Now set up the data and install the new mapping. */ - data = TD_V | TD_8K | TD_PA(pa) | TD_CP; + data = TD_V | TD_8K | TD_PA(pa); if (pm == kernel_pmap) data |= TD_P; if (prot & VM_PROT_WRITE) @@ -1578,6 +1598,8 @@ vm_offset_t va; struct tte *tp; + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_zero_page: fake page")); PMAP_STATS_INC(pmap_nzero_page); pa = VM_PAGE_TO_PHYS(m); if (m->md.color == -1) { @@ -1605,6 +1627,8 @@ vm_offset_t va; struct tte *tp; + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_zero_page_area: fake page")); KASSERT(off + size <= PAGE_SIZE, ("pmap_zero_page_area: bad off/size")); PMAP_STATS_INC(pmap_nzero_page_area); pa = VM_PAGE_TO_PHYS(m); @@ -1633,6 +1657,8 @@ vm_offset_t va; struct tte *tp; + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_zero_page_idle: fake page")); PMAP_STATS_INC(pmap_nzero_page_idle); pa = VM_PAGE_TO_PHYS(m); if (m->md.color == -1) { @@ -1662,6 +1688,10 @@ vm_offset_t vsrc; struct tte *tp; + KASSERT((mdst->flags & PG_FICTITIOUS) == 0, + ("pmap_copy_page: fake dst page")); + KASSERT((msrc->flags & PG_FICTITIOUS) == 0, + ("pmap_copy_page: fake src page")); PMAP_STATS_INC(pmap_ncopy_page); pdst = VM_PAGE_TO_PHYS(mdst); psrc = VM_PAGE_TO_PHYS(msrc); @@ -1770,6 +1800,8 @@ pmap_page_protect(vm_page_t m, vm_prot_t prot) { + KASSERT((m->flags & PG_FICTITIOUS) == 0, + ("pmap_page_protect: fake page")); if ((prot & VM_PROT_WRITE) == 0) { if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) pmap_clear_write(m); Index: sparc64/sparc64/tsb.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/tsb.c,v retrieving revision 1.30 diff -u -r1.30 tsb.c --- sparc64/sparc64/tsb.c 5 Jan 2003 05:30:40 -0000 1.30 +++ sparc64/sparc64/tsb.c 8 Feb 2003 19:47:51 -0000 @@ -154,16 +154,20 @@ } enter: - if ((m->flags & (PG_UNMANAGED | PG_FICTITIOUS)) == 0) { - pm->pm_stats.resident_count++; - data |= TD_PV; - } - if (pmap_cache_enter(m, va) != 0) - data |= TD_CV; + if ((m->flags & PG_FICTITIOUS) == 0) { + data |= TD_CP; + if ((m->flags & PG_UNMANAGED) == 0) { + pm->pm_stats.resident_count++; + data |= TD_PV; + } + if (pmap_cache_enter(m, va) != 0) + data |= TD_CV; + TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link); + } else + data |= TD_FAKE | TD_E; tp->tte_vpn = TV_VPN(va, sz); tp->tte_data = data; - TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link); return (tp); }