- * a fault; therefore, its page table entry
- * must remain valid for the duration.
- *
- * This routine is merely advisory; pmap_enter
- * will specify that these pages are to be wired
- * down (or not) as appropriate.
- */
-void
-pmap_pageable(
- __unused pmap_t pmap,
- __unused vm_offset_t start_addr,
- __unused vm_offset_t end_addr,
- __unused boolean_t pageable)
-{
-#ifdef lint
- pmap++; start_addr++; end_addr++; pageable++;
-#endif /* lint */
-}
-
-/*
- * Clear specified attribute bits.
- */
-void
-phys_attribute_clear(
- ppnum_t pn,
- int bits)
-{
- pv_entry_t pv_h;
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
- int pai;
- register pmap_t pmap;
- spl_t spl;
- pmap_paddr_t phys;
-
- assert(pn != vm_page_fictitious_addr);
- if (!valid_page(pn)) {
- /*
- * Not a managed page.
- */
- return;
- }
-
- /*
- * Lock the pmap system first, since we will be changing
- * several pmaps.
- */
-
- PMAP_WRITE_LOCK(spl);
- phys = i386_ptob(pn);
- pai = pa_index(phys);
- pv_h = pai_to_pvh(pai);
-
- /*
- * Walk down PV list, clearing all modify or reference bits.
- * We do not have to lock the pv_list because we have
- * the entire pmap system locked.
- */
- if (pv_h->pmap != PMAP_NULL) {
- /*
- * There are some mappings.
- */
- for (pv_e = pv_h; pv_e != PV_ENTRY_NULL; pv_e = pv_e->next) {
-
- pmap = pv_e->pmap;
- /*
- * Lock the pmap to block pmap_extract and similar routines.
- */
- simple_lock(&pmap->lock);
-
- {
- register vm_offset_t va;
-
- va = pv_e->va;
- pte = pmap_pte(pmap, va);
-
-#if 0
- /*
- * Consistency checks.
- */
- assert(*pte & INTEL_PTE_VALID);
- /* assert(pte_to_phys(*pte) == phys); */
-#endif
-
- /*
- * Clear modify or reference bits.
- */
-
- *pte++ &= ~bits;
- PMAP_UPDATE_TLBS(pmap, va, va + PAGE_SIZE);
- }
- simple_unlock(&pmap->lock);
-
- }
- }
-
- pmap_phys_attributes[pai] &= ~bits;
-
- PMAP_WRITE_UNLOCK(spl);
-}
-
-/*
- * Check specified attribute bits.
- */
-boolean_t
-phys_attribute_test(
- ppnum_t pn,
- int bits)
-{
- pv_entry_t pv_h;
- register pv_entry_t pv_e;
- register pt_entry_t *pte;
- int pai;
- register pmap_t pmap;
- spl_t spl;
- pmap_paddr_t phys;
-
- assert(pn != vm_page_fictitious_addr);
- if (!valid_page(pn)) {
- /*
- * Not a managed page.
- */
- return (FALSE);
- }
-
- /*
- * Lock the pmap system first, since we will be checking
- * several pmaps.
- */
-
- PMAP_WRITE_LOCK(spl);
- phys = i386_ptob(pn);
- pai = pa_index(phys);
- pv_h = pai_to_pvh(pai);
-
- if (pmap_phys_attributes[pai] & bits) {
- PMAP_WRITE_UNLOCK(spl);
- return (TRUE);
- }
-
- /*
- * Walk down PV list, checking all mappings.
- * We do not have to lock the pv_list because we have
- * the entire pmap system locked.
- */
- if (pv_h->pmap != PMAP_NULL) {
- /*
- * There are some mappings.
- */
- for (pv_e = pv_h; pv_e != PV_ENTRY_NULL; pv_e = pv_e->next) {
-
- pmap = pv_e->pmap;
- /*
- * Lock the pmap to block pmap_extract and similar routines.
- */
- simple_lock(&pmap->lock);
-
- {
- register vm_offset_t va;
-
- va = pv_e->va;
- pte = pmap_pte(pmap, va);
-
-#if 0
- /*
- * Consistency checks.
- */
- assert(*pte & INTEL_PTE_VALID);
- /* assert(pte_to_phys(*pte) == phys); */
-#endif
- }
-
- /*
- * Check modify or reference bits.
- */
- {
- if (*pte++ & bits) {
- simple_unlock(&pmap->lock);
- PMAP_WRITE_UNLOCK(spl);
- return (TRUE);
- }
- }
- simple_unlock(&pmap->lock);
- }
- }
- PMAP_WRITE_UNLOCK(spl);
- return (FALSE);
-}
-
-/*
- * Set specified attribute bits.
- */
-void
-phys_attribute_set(
- ppnum_t pn,
- int bits)
-{
- int spl;
- pmap_paddr_t phys;
-
- assert(pn != vm_page_fictitious_addr);
- if (!valid_page(pn)) {
- /*
- * Not a managed page.
- */
- return;
- }
-
- /*
- * Lock the pmap system and set the requested bits in
- * the phys attributes array. Don't need to bother with
- * ptes because the test routine looks here first.
- */
- phys = i386_ptob(pn);
- PMAP_WRITE_LOCK(spl);
- pmap_phys_attributes[pa_index(phys)] |= bits;
- PMAP_WRITE_UNLOCK(spl);
-}
-
-/*
- * Set the modify bit on the specified physical page.
- */
-
-void pmap_set_modify(
- ppnum_t pn)
-{
- phys_attribute_set(pn, PHYS_MODIFIED);
-}
-
-/*
- * Clear the modify bits on the specified physical page.
- */
-
-void
-pmap_clear_modify(
- ppnum_t pn)
-{
- phys_attribute_clear(pn, PHYS_MODIFIED);
-}
-
-/*
- * pmap_is_modified:
- *
- * Return whether or not the specified physical page is modified
- * by any physical maps.
- */
-
-boolean_t
-pmap_is_modified(
- ppnum_t pn)
-{
- return (phys_attribute_test(pn, PHYS_MODIFIED));
-}
-
-/*
- * pmap_clear_reference:
- *
- * Clear the reference bit on the specified physical page.
- */
-
-void
-pmap_clear_reference(
- ppnum_t pn)
-{
- phys_attribute_clear(pn, PHYS_REFERENCED);
-}
-
-void
-pmap_set_reference(ppnum_t pn)
-{
- phys_attribute_set(pn, PHYS_REFERENCED);
-}
-
-/*
- * pmap_is_referenced:
- *
- * Return whether or not the specified physical page is referenced
- * by any physical maps.
- */
-
-boolean_t
-pmap_is_referenced(
- ppnum_t pn)
-{
- return (phys_attribute_test(pn, PHYS_REFERENCED));
-}
-
-/*
- * pmap_get_refmod(phys)
- * returns the referenced and modified bits of the specified
- * physical page.
- */
-unsigned int
-pmap_get_refmod(ppnum_t pa)
-{
- return ( ((phys_attribute_test(pa, PHYS_MODIFIED))? VM_MEM_MODIFIED : 0)
- | ((phys_attribute_test(pa, PHYS_REFERENCED))? VM_MEM_REFERENCED : 0));
-}
-
-/*
- * pmap_clear_refmod(phys, mask)
- * clears the referenced and modified bits as specified by the mask
- * of the specified physical page.
- */
-void
-pmap_clear_refmod(ppnum_t pa, unsigned int mask)
-{
- unsigned int x86Mask;
-
- x86Mask = ( ((mask & VM_MEM_MODIFIED)? PHYS_MODIFIED : 0)
- | ((mask & VM_MEM_REFERENCED)? PHYS_REFERENCED : 0));
- phys_attribute_clear(pa, x86Mask);
-}
-
-/*
- * Set the modify bit on the specified range
- * of this map as requested.
- *
- * This optimization stands only if each time the dirty bit
- * in vm_page_t is tested, it is also tested in the pmap.
- */
-void
-pmap_modify_pages(
- pmap_t map,
- vm_offset_t s,
- vm_offset_t e)
-{
- spl_t spl;
- register pt_entry_t *pde;
- register pt_entry_t *spte, *epte;
- vm_offset_t l;
- vm_offset_t orig_s = s;
-
- if (map == PMAP_NULL)
- return;
-
- PMAP_READ_LOCK(map, spl);
-
- pde = pmap_pde(map, s);
- while (s && s < e) {
- l = (s + PDE_MAPPED_SIZE) & ~(PDE_MAPPED_SIZE-1);
- if (l > e)
- l = e;
- if (*pde & INTEL_PTE_VALID) {
- spte = (pt_entry_t *)pmap_pte(map, (s & ~(PDE_MAPPED_SIZE-1)));
- if (l) {
- spte = &spte[ptenum(s)];
- epte = &spte[intel_btop(l-s)];
- } else {
- epte = &spte[intel_btop(PDE_MAPPED_SIZE)];
- spte = &spte[ptenum(s)];
- }
- while (spte < epte) {
- if (*spte & INTEL_PTE_VALID) {
- *spte |= (INTEL_PTE_MOD | INTEL_PTE_WRITE);
- }
- spte++;
- }
- }
- s = l;
- pde++;
- }
- PMAP_UPDATE_TLBS(map, orig_s, e);
- PMAP_READ_UNLOCK(map, spl);