FreeBSD/sys/arm/arm/pmap-v6.c
/*
 *  This routine is called if the L2 page table
 *  is not mapped correctly.
 */
This routine is called if the L2 page table
is not mapped correctly.
This routine is called if the L2 page table is not mapped correctly .
static vm_page_t
_pmap_allocpte2(pmap_t pmap, vm_offset_t va, u_int flags)
{
	uint32_t pte1_idx;
	pt1_entry_t *pte1p;
	pt2_entry_t pte2;
	vm_page_t  m;
	vm_paddr_t pt2pg_pa, pt2_pa;
	pte1_idx = pte1_index(va);
	pte1p = pmap->pm_pt1 + pte1_idx;
	KASSERT(pte1_load(pte1p) == 0,
	    ("%s: pm_pt1[%#x] is not zero: %#x", __func__, pte1_idx,
	    pte1_load(pte1p)));
	pte2 = pt2tab_load(pmap_pt2tab_entry(pmap, va));
	if (!pte2_is_valid(pte2)) {
		m = vm_page_alloc(NULL, pte1_idx & ~PT2PG_MASK,
		    VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
		if (m == NULL) {
			if ((flags & PMAP_ENTER_NOSLEEP) == 0) {
				PMAP_UNLOCK(pmap);
				rw_wunlock(&pvh_global_lock);
				VM_WAIT;
				rw_wlock(&pvh_global_lock);
				PMAP_LOCK(pmap);
			}
			return (NULL);
		}
		pmap->pm_stats.resident_count++;
		pt2pg_pa = pmap_pt2pg_init(pmap, va, m);
	} else {
		pt2pg_pa = pte2_pa(pte2);
		m = PHYS_TO_VM_PAGE(pt2pg_pa);
	}
	pt2_wirecount_inc(m, pte1_idx);
	pt2_pa = page_pt2pa(pt2pg_pa, pte1_idx);
	pte1_store(pte1p, PTE1_LINK(pt2_pa));
	return (m);
}
static vm_page_t _pmap_allocpte2 ( pmap_t pmap , vm_offset_t va , u_int flags ) { uint32_t pte1_idx ; pt1_entry_t * pte1p ; pt2_entry_t pte2 ; vm_page_t m ; vm_paddr_t pt2pg_pa , pt2_pa ; pte1_idx = pte1_index ( va ) ; pte1p = pmap -> pm_pt1 + pte1_idx ; KASSERT ( pte1_load ( pte1p ) == 0 , ( " " , __func__ , pte1_idx , pte1_load ( pte1p ) ) ) ; pte2 = pt2tab_load ( pmap_pt2tab_entry ( pmap , va ) ) ; if ( ! pte2_is_valid ( pte2 ) ) { m = vm_page_alloc ( NULL , pte1_idx & ~ PT2PG_MASK , VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO ) ; if ( m == NULL ) { if ( ( flags & PMAP_ENTER_NOSLEEP ) == 0 ) { PMAP_UNLOCK ( pmap ) ; rw_wunlock ( & pvh_global_lock ) ; VM_WAIT ; rw_wlock ( & pvh_global_lock ) ; PMAP_LOCK ( pmap ) ; } return ( NULL ) ; } pmap -> pm_stats . resident_count ++ ; pt2pg_pa = pmap_pt2pg_init ( pmap , va , m ) ; } else { pt2pg_pa = pte2_pa ( pte2 ) ; m = PHYS_TO_VM_PAGE ( pt2pg_pa ) ; } pt2_wirecount_inc ( m , pte1_idx ) ; pt2_pa = page_pt2pa ( pt2pg_pa , pte1_idx ) ; pte1_store ( pte1p , PTE1_LINK ( pt2_pa ) ) ; return ( m ) ; }
This routine is called if the L2 page table
  is not mapped correctly.
This routine is called if the L2 page table is not mapped correctly .
/*
		 * Install new PT2s page into pmap PT2TAB.
		 */ /*
			 * Indicate the need to retry.  While waiting,
			 * the L2 page table page may have been allocated.
			 */