if (ctob(physmem) > 31*1024*1024 && MAXKPDE != NKPDE) { vm_offset_t p; int i;  p = pmap_steal_memory((MAXKPDE-NKPDE+1) * NBPG); bzero((void *)p, (MAXKPDE-NKPDE+1) * NBPG); p = round_page(p); for (i = NKPDE; i < MAXKPDE; i++, p += NBPG) PTD[KPTDI+i] = (pd_entry_t)p | PG_V | PG_KW; }
struct pv_entry * pmap_alloc_pv __P((void));void pmap_free_pv __P((struct pv_entry *));void i386_protection_init __P((void));void pmap_collect_pv __P((void));__inline void pmap_remove_pv __P((pmap_t, vm_offset_t, u_int));__inline void pmap_enter_pv __P((pmap_t, vm_offset_t, u_int));void pmap_deactivate __P((pmap_t, struct pcb *));void pmap_remove_all __P((vm_offset_t));void pads __P((pmap_t pm));void pmap_dump_pvlist __P((vm_offset_t phys, char *m));void pmap_pvdump __P((vm_offset_t pa));#if BSDVM_COMPAT#include <sys/msgbuf.h>/* * All those kernel PT submaps that BSD is so fond of */pt_entry_t	*CMAP1, *CMAP2, *XXX_mmap;caddr_t		CADDR1, CADDR2, vmmap;pt_entry_t	*msgbufmap;#endif	/* BSDVM_COMPAT *//* *	Bootstrap the system enough to run with virtual memory. *	Map the kernel's code and data, and allocate the system page table. * *	On the I386 this is called after mapping has already been enabled *	and just syncs the pmap module with what has already been done. *	[We can't call it easily with mapping off since the kernel is not *	mapped with PA == VA, hence we would have to relocate every address *	from the linked base (virtual) address to the actual (physical) *	address starting relative to 0] */voidpmap_bootstrap(virtual_start)	vm_offset_t virtual_start;{#if BSDVM_COMPAT	vm_offset_t va;	pt_entry_t *pte;#endif	/* XXX: allow for msgbuf */	avail_end -= i386_round_page(sizeof(struct msgbuf));	virtual_avail = virtual_start;	virtual_end = VM_MAX_KERNEL_ADDRESS;	/*	 * Initialize protection array.	 */	i386_protection_init();#ifdef notdef	/*	 * Create Kernel page directory table and page maps.	 * [ currently done in locore. i have wild and crazy ideas -wfj ]	 */	bzero(firstaddr, (1+NKPDE)*NBPG);	pmap_kernel()->pm_pdir = firstaddr + VM_MIN_KERNEL_ADDRESS;	pmap_kernel()->pm_ptab = firstaddr + VM_MIN_KERNEL_ADDRESS + NBPG;	firstaddr += NBPG;	for (x = i386_btod(VM_MIN_KERNEL_ADDRESS);	     x < i386_btod(VM_MIN_KERNEL_ADDRESS) + NKPDE; x++) {		pd_entry_t *pde;		pde = pmap_kernel()->pm_pdir + x;		*pde = (firstaddr + x*NBPG) | PG_V | PG_KW;	}#else	pmap_kernel()->pm_pdir =	    (pd_entry_t *)(proc0.p_addr->u_pcb.pcb_cr3 + KERNBASE);#endif	simple_lock_init(&pmap_kernel()->pm_lock);	pmap_kernel()->pm_count = 1;#if BSDVM_COMPAT	/*	 * Allocate all the submaps we need	 */#define	SYSMAP(c, p, v, n)	\	v = (c)va; va += ((n)*NBPG); p = pte; pte += (n);	va = virtual_avail;	pte = pmap_pte(pmap_kernel(), va);	SYSMAP(caddr_t		,CMAP1		,CADDR1	   ,1		)	SYSMAP(caddr_t		,CMAP2		,CADDR2	   ,1		)	SYSMAP(caddr_t		,XXX_mmap	,vmmap	   ,1		)	SYSMAP(struct msgbuf *	,msgbufmap	,msgbufp   ,1		)	virtual_avail = va;#endif	/*	 * Reserve pmap space for mapping physical pages during dump.	 */	virtual_avail = reserve_dumppages(virtual_avail);	/*	 * reserve special hunk of memory for use by bus dma as a bounce	 * buffer (contiguous virtual *and* physical memory).  XXX	 */#if NISA > 0 && NISADMA > 0	if (ctob(physmem) >= 0x1000000) {		isaphysmem = pmap_steal_memory(DMA_BOUNCE * NBPG);		isaphysmempgs = DMA_BOUNCE;	} else {		isaphysmem = pmap_steal_memory(DMA_BOUNCE_LOW * NBPG);		isaphysmempgs = DMA_BOUNCE_LOW;	}#endif	pmap_update();}voidpmap_virtual_space(startp, endp)	vm_offset_t *startp;	vm_offset_t *endp;{	*startp = virtual_avail;	*endp = virtual_end;}/* *	Initialize the pmap module. *	Called by vm_init, to initialize any structures that the pmap *	system needs to map virtual memory. */voidpmap_init(){	vm_offset_t addr;	vm_size_t s;	if (PAGE_SIZE != NBPG)		panic("pmap_init: CLSIZE != 1");	npages = pmap_page_index(avail_end - 1) + 1;	s = (vm_size_t) (sizeof(struct pv_entry) * npages + npages);	s = round_page(s);	addr = (vm_offset_t) kmem_alloc(kernel_map, s);	pv_table = (struct pv_entry *) addr;	addr += sizeof(struct pv_entry) * npages;	pmap_attributes = (char *) addr;	TAILQ_INIT(&pv_page_freelist);#ifdef DEBUG	if (pmapdebug & PDB_INIT)		printf("pmap_init: %x bytes (%x pgs): tbl %x attr %x\n",		       s, npages, pv_table, pmap_attributes);#endif	/*	 * Now it is safe to enable pv_table recording.	 */	pmap_initialized = TRUE;}struct pv_entry *pmap_alloc_pv(){	struct pv_page *pvp;	struct pv_entry *pv;	int i;	if (pv_nfree == 0) {		pvp = (struct pv_page *)kmem_alloc(kernel_map, NBPG);		if (pvp == 0)			panic("pmap_alloc_pv: kmem_alloc() failed");		pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1];		for (i = NPVPPG - 2; i; i--, pv++)			pv->pv_next = pv + 1;		pv->pv_next = 0;		pv_nfree += pvp->pvp_pgi.pgi_nfree = NPVPPG - 1;		TAILQ_INSERT_HEAD(&pv_page_freelist, pvp, pvp_pgi.pgi_list);		pv = &pvp->pvp_pv[0];	} else {		--pv_nfree;		pvp = pv_page_freelist.tqh_first;		if (--pvp->pvp_pgi.pgi_nfree == 0) {			TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list);		}		pv = pvp->pvp_pgi.pgi_freelist;#ifdef DIAGNOSTIC		if (pv == 0)			panic("pmap_alloc_pv: pgi_nfree inconsistent");#endif		pvp->pvp_pgi.pgi_freelist = pv->pv_next;	}	return pv;}