- * We also kick back a return code to say whether or not we had one to remove.
- *
- * We have a strict ordering here: the mapping must be removed from the PTEG hash list before
- * it can be removed from the physical entry list. This allows us to get by with only the PTEG
- * hash lock at page fault time. The physical entry lock must be held while we remove the mapping
- * from both lists. The PTEG lock is one of the lowest level locks. No PTE fault, interruptions,
- * losing control, getting other locks, etc., are allowed when you hold it. You do, and you die.
- * It's just that simple!
- *
- * When the phys_entry lock is held, the mappings chained to that one are guaranteed to stay around.
- * However, a mapping's order on the PTEG hash chain is not. The interrupt handler uses the PTEG
- * lock to control the hash cahin and may move the position of the mapping for MRU calculations.
- *
- * Note that mappings do not need to point to a physical entry. When they don't, it indicates
- * the mapping is outside of physical memory and usually refers to a memory mapped device of
- * some sort. Naturally, we can't lock what we don't have, so the phys entry lock and unlock
- * routines return normally, but don't do anything.
- */
-
-boolean_t mapping_remove(pmap_t pmap, vm_offset_t va) { /* Remove a single mapping for this VADDR
- Returns TRUE if a mapping was found to remove */
-
- mapping *mp, *mpv;
- register blokmap *blm;
- spl_t s;
- unsigned int *useadd, *useaddr;
- int i;
-
- debugLog2(1, va, pmap->space); /* start mapping_remove */
-
- s=splhigh(); /* Don't bother me */
-
- mp = hw_lock_phys_vir(pmap->space, va); /* Lock the physical entry for this mapping */
-
- if(!mp) { /* Did we find one? */
- if(mp = (mapping *)hw_rem_blk(pmap, va, va)) { /* No normal pages, try to remove an odd-sized one */
- splx(s); /* Allow 'rupts now */
-
- if((unsigned int)mp & 1) { /* Make sure we don't unmap a permanent one */
- blm = (blokmap *)hw_cpv((mapping *)((unsigned int)mp & 0xFFFFFFFE)); /* Get virtual address */
- panic("mapping_remove: attempt to unmap a permanent mapping - pmap = %08X, va = %08X, mapping = %08X\n",
- pmap, va, blm);
- }
-#if 0
- blm = (blokmap *)hw_cpv(mp); /* (TEST/DEBUG) */
- kprintf("mapping_remove: removed block map - bm=%08X; start=%08X; end=%08X; PTEr=%08X\n", /* (TEST/DEBUG) */
- blm, blm->start, blm->end, blm->PTEr);
-#endif
- mapping_free(hw_cpv(mp)); /* Release it */
- debugLog2(2, 1, 0); /* End mapping_remove */
- return TRUE; /* Tell them we did it */
- }
- splx(s); /* Restore the interrupt level */
- debugLog2(2, 0, 0); /* end mapping_remove */
- return FALSE; /* Didn't find any, return FALSE... */
- }
- if((unsigned int)mp&1) { /* Did we timeout? */
- panic("mapping_remove: timeout locking physical entry\n"); /* Yeah, scream about it! */
- splx(s); /* Restore the interrupt level */
- return FALSE; /* Bad hair day, return FALSE... */
- }
-
- mpv = hw_cpv(mp); /* Get virtual address of mapping */
-#if DEBUG
- if(hw_atomic_sub(&mpv->pmap->stats.resident_count, 1) < 0) panic("pmap resident count went negative\n");
-#else
- (void)hw_atomic_sub(&mpv->pmap->stats.resident_count, 1); /* Decrement the resident page count */
-#endif
- useadd = (unsigned int *)&pmap->pmapUsage[(va >> pmapUsageShft) & pmapUsageMask]; /* Point to slot to bump */
- useaddr = (unsigned int *)((unsigned int)useadd & -4); /* Round down to word */
- (void)hw_atomic_sub(useaddr, (useaddr == useadd) ? 0x00010000 : 1); /* Increment the even or odd slot */
-
-#if 0
- for(i = 0; i < (pmapUsageMask + 1); i++) { /* (TEST/DEBUG) */
- if((mpv->pmap->pmapUsage[i]) > 8192) { /* (TEST/DEBUG) */
- panic("mapping_remove: pmapUsage slot for %08X has invalid count (%d) for pmap %08X\n",
- i * pmapUsageSize, mpv->pmap->pmapUsage[i], mpv->pmap);
- }
- }
-#endif
-
- hw_rem_map(mp); /* Remove the corresponding mapping */
-
- if(mpv->physent)hw_unlock_bit((unsigned int *)&mpv->physent->phys_link, PHYS_LOCK); /* Unlock physical entry associated with mapping */
-
- splx(s); /* Was there something you needed? */
-
- mapping_free(mpv); /* Add mapping to the free list */
- debugLog2(2, 1, 0); /* end mapping_remove */
- return TRUE; /* Tell them we did it */
-}
-
-/*
- * mapping_purge_pmap(struct phys_entry *pp, pmap_t pmap) - release all mappings for this physent for the specified map