FreeBSD/sys/i386/i386/pmap.c
/*
 * Initialize a preallocated and zeroed pmap structure,
 * such as one in a vmspace structure.
 */
Initialize a preallocated and zeroed pmap structure,
such as one in a vmspace structure.
Initialize a preallocated and zeroed pmap structure such as one in a vmspace structure .
int
pmap_pinit(pmap_t pmap)
{
	vm_page_t m, ptdpg[NPGPTD];
	vm_paddr_t pa;
	int i;
	if (pmap->pm_pdir == NULL) {
		pmap->pm_pdir = (pd_entry_t *)kva_alloc(NBPTD);
		if (pmap->pm_pdir == NULL)
			return (0);
#if defined(PAE) || defined(PAE_TABLES)
		pmap->pm_pdpt = uma_zalloc(pdptzone, M_WAITOK | M_ZERO);
		KASSERT(((vm_offset_t)pmap->pm_pdpt &
		    ((NPGPTD * sizeof(pdpt_entry_t)) - 1)) == 0,
		    ("pmap_pinit: pdpt misaligned"));
		KASSERT(pmap_kextract((vm_offset_t)pmap->pm_pdpt) < (4ULL<<30),
		    ("pmap_pinit: pdpt above 4g"));
#endif
		pmap->pm_root.rt_root = 0;
	}
	KASSERT(vm_radix_is_empty(&pmap->pm_root),
	    ("pmap_pinit: pmap has reserved page table page(s)"));
	for (i = 0; i < NPGPTD;) {
		m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |
		    VM_ALLOC_WIRED | VM_ALLOC_ZERO);
		if (m == NULL)
			VM_WAIT;
		else {
			ptdpg[i++] = m;
		}
	}
	pmap_qenter((vm_offset_t)pmap->pm_pdir, ptdpg, NPGPTD);
	for (i = 0; i < NPGPTD; i++)
		if ((ptdpg[i]->flags & PG_ZERO) == 0)
			pagezero(pmap->pm_pdir + (i * NPDEPG));
	mtx_lock_spin(&allpmaps_lock);
	LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
	bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * sizeof(pd_entry_t));
	mtx_unlock_spin(&allpmaps_lock);
	for (i = 0; i < NPGPTD; i++) {
		pa = VM_PAGE_TO_PHYS(ptdpg[i]);
		pmap->pm_pdir[PTDPTDI + i] = pa | PG_V | PG_RW | PG_A | PG_M;
#if defined(PAE) || defined(PAE_TABLES)
		pmap->pm_pdpt[i] = pa | PG_V;
#endif
	}
	CPU_ZERO(&pmap->pm_active);
	TAILQ_INIT(&pmap->pm_pvchunk);
	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
	return (1);
}
int pmap_pinit ( pmap_t pmap ) { vm_page_t m , ptdpg [ NPGPTD ] ; vm_paddr_t pa ; int i ; if ( pmap -> pm_pdir == NULL ) { pmap -> pm_pdir = ( pd_entry_t * ) kva_alloc ( NBPTD ) ; if ( pmap -> pm_pdir == NULL ) return ( 0 ) ; #if defined ( PAE ) || defined ( PAE_TABLES ) pmap -> pm_pdpt = uma_zalloc ( pdptzone , M_WAITOK | M_ZERO ) ; KASSERT ( ( ( vm_offset_t ) pmap -> pm_pdpt & ( ( NPGPTD * sizeof ( pdpt_entry_t ) ) - 1 ) ) == 0 , ( " " ) ) ; KASSERT ( pmap_kextract ( ( vm_offset_t ) pmap -> pm_pdpt ) < ( 4ULL << 30 ) , ( " " ) ) ; #endif pmap -> pm_root . rt_root = 0 ; } KASSERT ( vm_radix_is_empty ( & pmap -> pm_root ) , ( " " ) ) ; for ( i = 0 ; i < NPGPTD ; ) { m = vm_page_alloc ( NULL , 0 , VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO ) ; if ( m == NULL ) VM_WAIT ; else { ptdpg [ i ++ ] = m ; } } pmap_qenter ( ( vm_offset_t ) pmap -> pm_pdir , ptdpg , NPGPTD ) ; for ( i = 0 ; i < NPGPTD ; i ++ ) if ( ( ptdpg [ i ] -> flags & PG_ZERO ) == 0 ) pagezero ( pmap -> pm_pdir + ( i * NPDEPG ) ) ; mtx_lock_spin ( & allpmaps_lock ) ; LIST_INSERT_HEAD ( & allpmaps , pmap , pm_list ) ; bcopy ( PTD + KPTDI , pmap -> pm_pdir + KPTDI , nkpt * sizeof ( pd_entry_t ) ) ; mtx_unlock_spin ( & allpmaps_lock ) ; for ( i = 0 ; i < NPGPTD ; i ++ ) { pa = VM_PAGE_TO_PHYS ( ptdpg [ i ] ) ; pmap -> pm_pdir [ PTDPTDI + i ] = pa | PG_V | PG_RW | PG_A | PG_M ; #if defined ( PAE ) || defined ( PAE_TABLES ) pmap -> pm_pdpt [ i ] = pa | PG_V ; #endif } CPU_ZERO ( & pmap -> pm_active ) ; TAILQ_INIT ( & pmap -> pm_pvchunk ) ; bzero ( & pmap -> pm_stats , sizeof pmap -> pm_stats ) ; return ( 1 ) ; }
Initialize a preallocated and zeroed pmap structure,
 such as one in a vmspace structure.
Initialize a preallocated and zeroed pmap structure such as one in a vmspace structure .
/*
	 * No need to allocate page table space yet but we do need a valid
	 * page directory table.
	 */ /*
	 * allocate the page directory page(s)
	 */ /* Copy the kernel page table directory entries. */ /* install self-referential address mapping entry(s) */