FreeBSD/sys/arm/arm/pmap-v6.c
/*
 *  Grow the number of kernel L2 page table entries, if needed.
 */
Grow the number of kernel L2 page table entries, if needed.
Grow the number of kernel L2 page table entries if needed .
void
pmap_growkernel(vm_offset_t addr)
{
	vm_page_t m;
	vm_paddr_t pt2pg_pa, pt2_pa;
	pt1_entry_t pte1;
	pt2_entry_t pte2;
	PDEBUG(1, printf("%s: addr = %#x\n", __func__, addr));
	kernel_vm_end = pte1_roundup(kernel_vm_end);
	mtx_assert(&kernel_map->system_mtx, MA_OWNED);
	addr = roundup2(addr, PTE1_SIZE);
	if (addr - 1 >= kernel_map->max_offset)
		addr = kernel_map->max_offset;
	while (kernel_vm_end < addr) {
		pte1 = pte1_load(kern_pte1(kernel_vm_end));
		if (pte1_is_valid(pte1)) {
			kernel_vm_end += PTE1_SIZE;
			if (kernel_vm_end - 1 >= kernel_map->max_offset) {
				kernel_vm_end = kernel_map->max_offset;
				break;
			}
			continue;
		}
		kernel_vm_end_new = kernel_vm_end + PTE1_SIZE;
		pte2 = pt2tab_load(kern_pt2tab_entry(kernel_vm_end));
		if (!pte2_is_valid(pte2)) {
			m = vm_page_alloc(NULL,
			    pte1_index(kernel_vm_end) & ~PT2PG_MASK,
			    VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ |
			    VM_ALLOC_WIRED | VM_ALLOC_ZERO);
			if (m == NULL)
				panic("%s: no memory to grow kernel", __func__);
			pt2pg_pa = pmap_pt2pg_init(kernel_pmap, kernel_vm_end,
			    m);
		} else
			pt2pg_pa = pte2_pa(pte2);
		pt2_pa = page_pt2pa(pt2pg_pa, pte1_index(kernel_vm_end));
		pmap_kenter_pte1(kernel_vm_end, PTE1_LINK(pt2_pa));
		kernel_vm_end = kernel_vm_end_new;
		if (kernel_vm_end - 1 >= kernel_map->max_offset) {
			kernel_vm_end = kernel_map->max_offset;
			break;
		}
	}
}
void pmap_growkernel ( vm_offset_t addr ) { vm_page_t m ; vm_paddr_t pt2pg_pa , pt2_pa ; pt1_entry_t pte1 ; pt2_entry_t pte2 ; PDEBUG ( 1 , printf ( " \n " , __func__ , addr ) ) ; kernel_vm_end = pte1_roundup ( kernel_vm_end ) ; mtx_assert ( & kernel_map -> system_mtx , MA_OWNED ) ; addr = roundup2 ( addr , PTE1_SIZE ) ; if ( addr - 1 >= kernel_map -> max_offset ) addr = kernel_map -> max_offset ; while ( kernel_vm_end < addr ) { pte1 = pte1_load ( kern_pte1 ( kernel_vm_end ) ) ; if ( pte1_is_valid ( pte1 ) ) { kernel_vm_end += PTE1_SIZE ; if ( kernel_vm_end - 1 >= kernel_map -> max_offset ) { kernel_vm_end = kernel_map -> max_offset ; break ; } continue ; } kernel_vm_end_new = kernel_vm_end + PTE1_SIZE ; pte2 = pt2tab_load ( kern_pt2tab_entry ( kernel_vm_end ) ) ; if ( ! pte2_is_valid ( pte2 ) ) { m = vm_page_alloc ( NULL , pte1_index ( kernel_vm_end ) & ~ PT2PG_MASK , VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO ) ; if ( m == NULL ) panic ( " " , __func__ ) ; pt2pg_pa = pmap_pt2pg_init ( kernel_pmap , kernel_vm_end , m ) ; } else pt2pg_pa = pte2_pa ( pte2 ) ; pt2_pa = page_pt2pa ( pt2pg_pa , pte1_index ( kernel_vm_end ) ) ; pmap_kenter_pte1 ( kernel_vm_end , PTE1_LINK ( pt2_pa ) ) ; kernel_vm_end = kernel_vm_end_new ; if ( kernel_vm_end - 1 >= kernel_map -> max_offset ) { kernel_vm_end = kernel_map -> max_offset ; break ; } } }
Grow the number of kernel L2 page table entries, if needed.
Grow the number of kernel L2 page table entries if needed .
/*
	 * All the time kernel_vm_end is first KVA for which underlying
	 * L2 page table is either not allocated or linked from L1 page table
	 * (not considering sections). Except for two possible cases:
	 *
	 *   (1) in the very beginning as long as pmap_growkernel() was
	 *       not called, it could be first unused KVA (which is not
	 *       rounded up to PTE1_SIZE),
	 *
	 *   (2) when all KVA space is mapped and kernel_map->max_offset
	 *       address is not rounded up to PTE1_SIZE. (For example,
	 *       it could be 0xFFFFFFFF.)
	 */ /*
		 * kernel_vm_end_new is used in pmap_pinit() when kernel
		 * mappings are entered to new pmap all at once to avoid race
		 * between pmap_kenter_pte1() and kernel_vm_end increase.
		 * The same aplies to pmap_kenter_pt2tab().
		 */ /*
			 * Install new PT2s page into kernel PT2TAB.
			 */ /*
			 * QQQ: To link all new L2 page tables from L1 page
			 *      table now and so pmap_kenter_pte1() them
			 *      at once together with pmap_kenter_pt2tab()
			 *      could be nice speed up. However,
			 *      pmap_growkernel() does not happen so often...
			 * QQQ: The other TTBR is another option.
			 */