FreeBSD/sys/arm/arm/pmap-v6.c
/*
 *  Initialize the pmap module.
 *  Called by vm_init, to initialize any structures that the pmap
 *  system needs to map virtual memory.
 */
Initialize the pmap module.
Called by vm_init, to initialize any structures that the pmap
system needs to map virtual memory.
Initialize the pmap module . Called by vm_init to initialize any structures that the pmap system needs to map virtual memory .
void
pmap_init(void)
{
	vm_size_t s;
	pt2_entry_t *pte2p, pte2;
	u_int i, pte1_idx, pv_npg;
	PDEBUG(1, printf("%s: phys_start = %#x\n", __func__, PHYSADDR));
	pte1_idx = pte1_index(KERNBASE - PT2MAP_SIZE);
	pte2p = kern_pt2tab_entry(KERNBASE - PT2MAP_SIZE);
	for (i = 0; i < nkpt2pg + NPG_IN_PT2TAB; i++, pte2p++) {
		vm_paddr_t pa;
		vm_page_t m;
		pte2 = pte2_load(pte2p);
		KASSERT(pte2_is_valid(pte2), ("%s: no valid entry", __func__));
		pa = pte2_pa(pte2);
		m = PHYS_TO_VM_PAGE(pa);
		KASSERT(m >= vm_page_array &&
		    m < &vm_page_array[vm_page_array_size],
		    ("%s: L2 page table page is out of range", __func__));
		m->pindex = pte1_idx;
		m->phys_addr = pa;
		pte1_idx += NPT2_IN_PG;
	}
	TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
	pv_entry_max = shpgperproc * maxproc + vm_cnt.v_page_count;
	TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
	pv_entry_max = roundup(pv_entry_max, _NPCPV);
	pv_entry_high_water = 9 * (pv_entry_max / 10);
	TUNABLE_INT_FETCH("vm.pmap.sp_enabled", &sp_enabled);
	if (sp_enabled) {
		KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
		    ("%s: can't assign to pagesizes[1]", __func__));
		pagesizes[1] = PTE1_SIZE;
	}
	first_managed_pa = pte1_trunc(vm_phys_segs[0].start);
	pv_npg = (pte1_trunc(vm_phys_segs[vm_phys_nsegs - 1].end - PAGE_SIZE)
	    - first_managed_pa) / PTE1_SIZE + 1;
	s = (vm_size_t)(pv_npg * sizeof(struct md_page));
	s = round_page(s);
	pv_table = (struct md_page *)kmem_malloc(kernel_arena, s,
	    M_WAITOK | M_ZERO);
	for (i = 0; i < pv_npg; i++)
		TAILQ_INIT(&pv_table[i].pv_list);
	pv_maxchunks = MAX(pv_entry_max / _NPCPV, maxproc);
	pv_chunkbase = (struct pv_chunk *)kva_alloc(PAGE_SIZE * pv_maxchunks);
	if (pv_chunkbase == NULL)
		panic("%s: not enough kvm for pv chunks", __func__);
	pmap_pte2list_init(&pv_vafree, pv_chunkbase, pv_maxchunks);
}
void pmap_init ( void ) { vm_size_t s ; pt2_entry_t * pte2p , pte2 ; u_int i , pte1_idx , pv_npg ; PDEBUG ( 1 , printf ( " \n " , __func__ , PHYSADDR ) ) ; pte1_idx = pte1_index ( KERNBASE - PT2MAP_SIZE ) ; pte2p = kern_pt2tab_entry ( KERNBASE - PT2MAP_SIZE ) ; for ( i = 0 ; i < nkpt2pg + NPG_IN_PT2TAB ; i ++ , pte2p ++ ) { vm_paddr_t pa ; vm_page_t m ; pte2 = pte2_load ( pte2p ) ; KASSERT ( pte2_is_valid ( pte2 ) , ( " " , __func__ ) ) ; pa = pte2_pa ( pte2 ) ; m = PHYS_TO_VM_PAGE ( pa ) ; KASSERT ( m >= vm_page_array && m < & vm_page_array [ vm_page_array_size ] , ( " " , __func__ ) ) ; m -> pindex = pte1_idx ; m -> phys_addr = pa ; pte1_idx += NPT2_IN_PG ; } TUNABLE_INT_FETCH ( " " , & shpgperproc ) ; pv_entry_max = shpgperproc * maxproc + vm_cnt . v_page_count ; TUNABLE_INT_FETCH ( " " , & pv_entry_max ) ; pv_entry_max = roundup ( pv_entry_max , _NPCPV ) ; pv_entry_high_water = 9 * ( pv_entry_max / 10 ) ; TUNABLE_INT_FETCH ( " " , & sp_enabled ) ; if ( sp_enabled ) { KASSERT ( MAXPAGESIZES > 1 && pagesizes [ 1 ] == 0 , ( " " , __func__ ) ) ; pagesizes [ 1 ] = PTE1_SIZE ; } first_managed_pa = pte1_trunc ( vm_phys_segs [ 0 ] . start ) ; pv_npg = ( pte1_trunc ( vm_phys_segs [ vm_phys_nsegs - 1 ] . end - PAGE_SIZE ) - first_managed_pa ) / PTE1_SIZE + 1 ; s = ( vm_size_t ) ( pv_npg * sizeof ( struct md_page ) ) ; s = round_page ( s ) ; pv_table = ( struct md_page * ) kmem_malloc ( kernel_arena , s , M_WAITOK | M_ZERO ) ; for ( i = 0 ; i < pv_npg ; i ++ ) TAILQ_INIT ( & pv_table [ i ] . pv_list ) ; pv_maxchunks = MAX ( pv_entry_max / _NPCPV , maxproc ) ; pv_chunkbase = ( struct pv_chunk * ) kva_alloc ( PAGE_SIZE * pv_maxchunks ) ; if ( pv_chunkbase == NULL ) panic ( " " , __func__ ) ; pmap_pte2list_init ( & pv_vafree , pv_chunkbase , pv_maxchunks ) ; }
Initialize the pmap module.
Initialize the pmap module .
/*
	 * Initialize the vm page array entries for kernel pmap's
	 * L2 page table pages allocated in advance.
	 */ /*
	 * Initialize the address space (zone) for the pv entries.  Set a
	 * high water mark so that the system can recover from excessive
	 * numbers of pv entries.
	 */ /*
	 * Are large page mappings enabled?
	 */ /*
	 * Calculate the size of the pv head table for sections.
	 * Handle the possibility that "vm_phys_segs[...].end" is zero.
	 * Note that the table is only for sections which could be promoted.
	 */ /*
	 * Allocate memory for the pv head table for sections.
	 */