pool_init(&pmap_pdp_pool, PAGE_SIZE, 0, 0, 0, "pdppl", 0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP); pool_cache_init(&pmap_pdp_cache, &pmap_pdp_pool, pmap_pdp_ctor, NULL, NULL);
pmap_bootstrap(kva_start)	vaddr_t kva_start;{	struct pmap *kpm;	vaddr_t kva;	pt_entry_t *pte;	/*	 * set the page size (default value is 4K which is ok)	 */	uvm_setpagesize();	/*	 * a quick sanity check	 */	if (PAGE_SIZE != NBPG)		panic("pmap_bootstrap: PAGE_SIZE != NBPG");	/*	 * use the very last page of physical memory for the message buffer	 */	avail_end -= i386_round_page(MSGBUFSIZE);	/*	 * The arguments passed in from /boot needs space too.	 */	avail_end -= i386_round_page(bootargc);	/*	 * set up our local static global vars that keep track of the	 * usage of KVM before kernel_map is set up	 */	virtual_avail = kva_start;		/* first free KVA */	virtual_end = VM_MAX_KERNEL_ADDRESS;	/* last KVA */	/*	 * set up protection_codes: we need to be able to convert from	 * a MI protection code (some combo of VM_PROT...) to something	 * we can jam into a i386 PTE.	 */	protection_codes[VM_PROT_NONE] = 0;  			/* --- */	protection_codes[VM_PROT_EXECUTE] = PG_RO;		/* --x */	protection_codes[VM_PROT_READ] = PG_RO;			/* -r- */	protection_codes[VM_PROT_READ|VM_PROT_EXECUTE] = PG_RO;	/* -rx */	protection_codes[VM_PROT_WRITE] = PG_RW;		/* w-- */	protection_codes[VM_PROT_WRITE|VM_PROT_EXECUTE] = PG_RW;/* w-x */	protection_codes[VM_PROT_WRITE|VM_PROT_READ] = PG_RW;	/* wr- */	protection_codes[VM_PROT_ALL] = PG_RW;			/* wrx */	/*	 * now we init the kernel's pmap	 *	 * the kernel pmap's pm_obj is not used for much.   however, in	 * user pmaps the pm_obj contains the list of active PTPs.	 * the pm_obj currently does not have a pager.   it might be possible	 * to add a pager that would allow a process to read-only mmap its	 * own page tables (fast user level vtophys?).   this may or may not	 * be useful.	 */	kpm = pmap_kernel();	simple_lock_init(&kpm->pm_obj.vmobjlock);	kpm->pm_obj.pgops = NULL;	TAILQ_INIT(&kpm->pm_obj.memq);	kpm->pm_obj.uo_npages = 0;	kpm->pm_obj.uo_refs = 1;	bzero(&kpm->pm_list, sizeof(kpm->pm_list));  /* pm_list not used */	kpm->pm_pdir = (pd_entry_t *)(proc0.p_addr->u_pcb.pcb_cr3 + KERNBASE);	kpm->pm_pdirpa = (u_int32_t) proc0.p_addr->u_pcb.pcb_cr3;	kpm->pm_stats.wired_count = kpm->pm_stats.resident_count =		i386_btop(kva_start - VM_MIN_KERNEL_ADDRESS);	/*	 * the above is just a rough estimate and not critical to the proper	 * operation of the system.	 */	curpcb->pcb_pmap = kpm;	/* proc0's pcb */	/*	 * enable global TLB entries if they are supported	 */	if (cpu_feature & CPUID_PGE) {		lcr4(rcr4() | CR4_PGE);	/* enable hardware (via %cr4) */		pmap_pg_g = PG_G;		/* enable software */		/* add PG_G attribute to already mapped kernel pages */		for (kva = VM_MIN_KERNEL_ADDRESS ; kva < virtual_avail ;		     kva += PAGE_SIZE)			if (pmap_valid_entry(PTE_BASE[i386_btop(kva)]))				PTE_BASE[i386_btop(kva)] |= PG_G;	}#ifdef LARGEPAGES	/*	 * enable large pages of they are supported.	 */	if (cpu_feature & CPUID_PSE) {		paddr_t pa;		vaddr_t kva_end;		pd_entry_t *pde;		extern char _etext;		lcr4(rcr4() | CR4_PSE);	/* enable hardware (via %cr4) */		pmap_largepages = 1;	/* enable software */		/*		 * the TLB must be flushed after enabling large pages		 * on Pentium CPUs, according to section 3.6.2.2 of		 * "Intel Architecture Software Developer's Manual,		 * Volume 3: System Programming".		 */		tlbflush();		/*		 * now, remap the kernel text using large pages.  we		 * assume that the linker has properly aligned the		 * .data segment to a 4MB boundary.		 */		kva_end = roundup((vaddr_t)&_etext, NBPD);		for (pa = 0, kva = KERNBASE; kva < kva_end;		     kva += NBPD, pa += NBPD) {			pde = &kpm->pm_pdir[pdei(kva)];			*pde = pa | pmap_pg_g | PG_PS |			    PG_KR | PG_V;	/* zap! */			tlbflush();		}	}#endif /* LARGEPAGES */	/*	 * now we allocate the "special" VAs which are used for tmp mappings	 * by the pmap (and other modules).    we allocate the VAs by advancing	 * virtual_avail (note that there are no pages mapped at these VAs).	 * we find the PTE that maps the allocated VA via the linear PTE	 * mapping.	 */	pte = PTE_BASE + i386_btop(virtual_avail);	csrcp = (caddr_t) virtual_avail;  csrc_pte = pte;	/* allocate */	virtual_avail += PAGE_SIZE; pte++;			/* advance */	cdstp = (caddr_t) virtual_avail;  cdst_pte = pte;	virtual_avail += PAGE_SIZE; pte++;	zerop = (caddr_t) virtual_avail;  zero_pte = pte;	virtual_avail += PAGE_SIZE; pte++;	ptpp = (caddr_t) virtual_avail;  ptp_pte = pte;	virtual_avail += PAGE_SIZE; pte++;	/* XXX: vmmap used by mem.c... should be uvm_map_reserve */	vmmap = (char *)virtual_avail;			/* don't need pte */	virtual_avail += PAGE_SIZE; pte++;#ifdef __NetBSD	msgbuf_vaddr = virtual_avail;			/* don't need pte */#endif#ifdef __OpenBSD__	msgbufp = (struct msgbuf *)virtual_avail;	/* don't need pte */#endif	virtual_avail += round_page(MSGBUFSIZE); pte++;#ifdef __NetBSD__	idt_vaddr = virtual_avail;			/* don't need pte */	virtual_avail += PAGE_SIZE; pte++;	idt_paddr = avail_start;			/* steal a page */	avail_start += PAGE_SIZE;#if defined(I586_CPU)	/* pentium f00f bug stuff */	pentium_idt_vaddr = virtual_avail;		/* don't need pte */	virtual_avail += PAGE_SIZE; pte++;#endif#endif#ifdef __OpenBSD__	bootargp = (bootarg_t *)virtual_avail;	virtual_avail += round_page(bootargc); pte++;#endif	/*	 * now we reserve some VM for mapping pages when doing a crash dump	 */	virtual_avail = reserve_dumppages(virtual_avail);	/*	 * init the static-global locks and global lists.	 */	spinlockinit(&pmap_main_lock, "pmaplk", 0);	simple_lock_init(&pvalloc_lock);	simple_lock_init(&pmaps_lock);	simple_lock_init(&pmap_copy_page_lock);	simple_lock_init(&pmap_zero_page_lock);	simple_lock_init(&pmap_tmpptp_lock);	LIST_INIT(&pmaps);	TAILQ_INIT(&pv_freepages);	TAILQ_INIT(&pv_unusedpgs);	/*	 * initialize the pmap pool.	 */	pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",		  0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);  	/*	 * initialize the PDE pool and cache.	 */	pool_init(&pmap_pdp_pool, PAGE_SIZE, 0, 0, 0, "pdppl",		  0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP);	pool_cache_init(&pmap_pdp_cache, &pmap_pdp_pool,			pmap_pdp_ctor, NULL, NULL);	/*	 * ensure the TLB is sync'd with reality by flushing it...	 */	tlbflush();}