lev3mapsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
lev3mapsize = (VM_PHYS_SIZE +
pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids){	vsize_t lev2mapsize, lev3mapsize;	pt_entry_t *lev2map, *lev3map;	pt_entry_t pte;	int i;#ifdef DEBUG	if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))		printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn);#endif	/*	 * Compute the number of pages kmem_map will have.	 */	kmeminit_nkmempages();	/*	 * Figure out how many PTE's are necessary to map the kernel.	 */	lev3mapsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +		nbuf * MAXBSIZE + 16 * NCARGS + PAGER_MAP_SIZE) / NBPG +		(maxproc * UPAGES) + nkmempages;#ifdef SYSVSHM	lev3mapsize += shminfo.shmall;#endif	lev3mapsize = roundup(lev3mapsize, NPTEPG);	/*	 * Allocate a level 1 PTE table for the kernel.	 * This is always one page long.	 * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.	 */	kernel_lev1map = (pt_entry_t *)	    pmap_steal_memory(sizeof(pt_entry_t) * NPTEPG, NULL, NULL);	/*	 * Allocate a level 2 PTE table for the kernel.	 * These must map all of the level3 PTEs.	 * IF THIS IS NOT A MULTIPLE OF NBPG, ALL WILL GO TO HELL.	 */	lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG);	lev2map = (pt_entry_t *)	    pmap_steal_memory(sizeof(pt_entry_t) * lev2mapsize, NULL, NULL);	/*	 * Allocate a level 3 PTE table for the kernel.	 * Contains lev3mapsize PTEs.	 */	lev3map = (pt_entry_t *)	    pmap_steal_memory(sizeof(pt_entry_t) * lev3mapsize, NULL, NULL);	/*	 * Allocate memory for the pv_heads.  (A few more of the latter	 * are allocated than are needed.)	 *	 * We could do this in pmap_init when we know the actual	 * managed page pool size, but its better to use kseg0	 * addresses rather than kernel virtual addresses mapped	 * through the TLB.	 */	pv_table_npages = physmem;	pv_table = (struct pv_head *)	    pmap_steal_memory(sizeof(struct pv_head) * pv_table_npages,	    NULL, NULL);	/*	 * ...and intialize the pv_entry list headers.	 */	for (i = 0; i < pv_table_npages; i++) {		LIST_INIT(&pv_table[i].pvh_list);		simple_lock_init(&pv_table[i].pvh_slock);	}	/*	 * Set up level 1 page table	 */	/* Map all of the level 2 pte pages */	for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) {		pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) +		    (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;		pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;		kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS +		    (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;	}	/* Map the virtual page table */	pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT)	    << PG_SHIFT;	pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */	kernel_lev1map[l1pte_index(VPTBASE)] = pte;	VPT = (pt_entry_t *)VPTBASE;#ifdef _PMAP_MAY_USE_PROM_CONSOLE    {	extern pt_entry_t prom_pte;			/* XXX */	extern int prom_mapped;				/* XXX */	if (pmap_uses_prom_console()) {		/*		 * XXX Save old PTE so we can remap the PROM, if		 * XXX necessary.		 */		prom_pte = *(pt_entry_t *)ptaddr & ~PG_ASM;	}	prom_mapped = 0;	/*	 * Actually, this code lies.  The prom is still mapped, and will	 * remain so until the context switch after alpha_init() returns.	 */    }#endif	/*	 * Set up level 2 page table.	 */	/* Map all of the level 3 pte pages */	for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) {		pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) +		    (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;		pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;		lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+		    (i*PAGE_SIZE*NPTEPG))] = pte;	}	/* Initialize the pmap_growkernel_slock. */	simple_lock_init(&pmap_growkernel_slock);	/*	 * Set up level three page table (lev3map)	 */	/* Nothing to do; it's already zero'd */	/*	 * Initialize `FYI' variables.  Note we're relying on	 * the fact that BSEARCH sorts the vm_physmem[] array	 * for us.	 */	avail_start = ptoa(vm_physmem[0].start);	avail_end = ptoa(vm_physmem[vm_nphysseg - 1].end);	virtual_avail = VM_MIN_KERNEL_ADDRESS;	virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE;#if 0	printf("avail_start = 0x%lx\n", avail_start);	printf("avail_end = 0x%lx\n", avail_end);	printf("virtual_avail = 0x%lx\n", virtual_avail);	printf("virtual_end = 0x%lx\n", virtual_end);#endif	/*	 * Intialize the pmap pools and list.	 */	pmap_ncpuids = ncpuids;	pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",	    0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);	pool_init(&pmap_l1pt_pool, PAGE_SIZE, 0, 0, 0, "l1ptpl",	    0, pmap_l1pt_alloc, pmap_l1pt_free, M_VMPMAP);	pool_cache_init(&pmap_l1pt_cache, &pmap_l1pt_pool, pmap_l1pt_ctor,	    NULL, NULL);	pool_init(&pmap_asn_pool, pmap_ncpuids * sizeof(u_int), 0, 0, 0,	    "pmasnpl",	    0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);	pool_init(&pmap_asngen_pool, pmap_ncpuids * sizeof(u_long), 0, 0, 0,	    "pmasngenpl",	    0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);	pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",	    0, pmap_pv_page_alloc, pmap_pv_page_free, M_VMPMAP);	TAILQ_INIT(&pmap_all_pmaps);	/*	 * Initialize the ASN logic.	 */	pmap_max_asn = maxasn;	for (i = 0; i < ALPHA_MAXPROCS; i++) {		pmap_next_asn[i] = 1;		pmap_asn_generation[i] = 0;	}	/*	 * Initialize the locks.	 */	spinlockinit(&pmap_main_lock, "pmaplk", 0);	simple_lock_init(&pmap_all_pmaps_slock);	/*	 * Initialize kernel pmap.  Note that all kernel mappings	 * have PG_ASM set, so the ASN doesn't really matter for	 * the kernel pmap.  Also, since the kernel pmap always	 * references kernel_lev1map, it always has an invalid ASN	 * generation.	 */	memset(pmap_kernel(), 0, sizeof(struct pmap));	pmap_kernel()->pm_lev1map = kernel_lev1map;	pmap_kernel()->pm_count = 1;	pmap_kernel()->pm_asn = kernel_pmap_asn_store;	pmap_kernel()->pm_asngen = kernel_pmap_asngen_store;	for (i = 0; i < ALPHA_MAXPROCS; i++) {		pmap_kernel()->pm_asn[i] = PMAP_ASN_RESERVED;		pmap_kernel()->pm_asngen[i] = pmap_asn_generation[i];	}	simple_lock_init(&pmap_kernel()->pm_slock);	TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list);#if defined(MULTIPROCESSOR)	/*	 * Initialize the TLB shootdown queues.	 */	pool_init(&pmap_tlb_shootdown_job_pool,	    sizeof(struct pmap_tlb_shootdown_job), 0, 0, 0, "pmaptlbpl",	    0, NULL, NULL, M_VMPMAP);	for (i = 0; i < ALPHA_MAXPROCS; i++) {		TAILQ_INIT(&pmap_tlb_shootdown_q[i].pq_head);		simple_lock_init(&pmap_tlb_shootdown_q[i].pq_slock);	}#endif	/*	 * Set up proc0's PCB such that the ptbr points to the right place	 * and has the kernel pmap's (really unused) ASN.	 */	proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr =	    ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT;	proc0.p_addr->u_pcb.pcb_hw.apcb_asn =	    pmap_kernel()->pm_asn[cpu_number()];	/*	 * Mark the kernel pmap `active' on this processor.	 */	atomic_setbits_ulong(&pmap_kernel()->pm_cpus,	    (1UL << cpu_number()));}