Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 1,738 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
vm_paddr_t paddr; | vm_paddr_t paddr; | ||||
vm_page_t nkpg; | vm_page_t nkpg; | ||||
pd_entry_t *l0, *l1, *l2; | pd_entry_t *l0, *l1, *l2; | ||||
mtx_assert(&kernel_map->system_mtx, MA_OWNED); | mtx_assert(&kernel_map->system_mtx, MA_OWNED); | ||||
addr = roundup2(addr, L2_SIZE); | addr = roundup2(addr, L2_SIZE); | ||||
if (addr - 1 >= kernel_map->max_offset) | if (addr - 1 >= vm_map_max(kernel_map)) | ||||
addr = kernel_map->max_offset; | addr = vm_map_max(kernel_map); | ||||
while (kernel_vm_end < addr) { | while (kernel_vm_end < addr) { | ||||
l0 = pmap_l0(kernel_pmap, kernel_vm_end); | l0 = pmap_l0(kernel_pmap, kernel_vm_end); | ||||
KASSERT(pmap_load(l0) != 0, | KASSERT(pmap_load(l0) != 0, | ||||
("pmap_growkernel: No level 0 kernel entry")); | ("pmap_growkernel: No level 0 kernel entry")); | ||||
l1 = pmap_l0_to_l1(l0, kernel_vm_end); | l1 = pmap_l0_to_l1(l0, kernel_vm_end); | ||||
if (pmap_load(l1) == 0) { | if (pmap_load(l1) == 0) { | ||||
/* We need a new PDP entry */ | /* We need a new PDP entry */ | ||||
nkpg = vm_page_alloc(NULL, kernel_vm_end >> L1_SHIFT, | nkpg = vm_page_alloc(NULL, kernel_vm_end >> L1_SHIFT, | ||||
VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | | VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | | ||||
VM_ALLOC_WIRED | VM_ALLOC_ZERO); | VM_ALLOC_WIRED | VM_ALLOC_ZERO); | ||||
if (nkpg == NULL) | if (nkpg == NULL) | ||||
panic("pmap_growkernel: no memory to grow kernel"); | panic("pmap_growkernel: no memory to grow kernel"); | ||||
if ((nkpg->flags & PG_ZERO) == 0) | if ((nkpg->flags & PG_ZERO) == 0) | ||||
pmap_zero_page(nkpg); | pmap_zero_page(nkpg); | ||||
paddr = VM_PAGE_TO_PHYS(nkpg); | paddr = VM_PAGE_TO_PHYS(nkpg); | ||||
pmap_load_store(l1, paddr | L1_TABLE); | pmap_load_store(l1, paddr | L1_TABLE); | ||||
continue; /* try again */ | continue; /* try again */ | ||||
} | } | ||||
l2 = pmap_l1_to_l2(l1, kernel_vm_end); | l2 = pmap_l1_to_l2(l1, kernel_vm_end); | ||||
if ((pmap_load(l2) & ATTR_AF) != 0) { | if ((pmap_load(l2) & ATTR_AF) != 0) { | ||||
kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET; | kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET; | ||||
if (kernel_vm_end - 1 >= kernel_map->max_offset) { | if (kernel_vm_end - 1 >= vm_map_max(kernel_map)) { | ||||
kernel_vm_end = kernel_map->max_offset; | kernel_vm_end = vm_map_max(kernel_map); | ||||
break; | break; | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
nkpg = vm_page_alloc(NULL, kernel_vm_end >> L2_SHIFT, | nkpg = vm_page_alloc(NULL, kernel_vm_end >> L2_SHIFT, | ||||
VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | | VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | | ||||
VM_ALLOC_ZERO); | VM_ALLOC_ZERO); | ||||
if (nkpg == NULL) | if (nkpg == NULL) | ||||
panic("pmap_growkernel: no memory to grow kernel"); | panic("pmap_growkernel: no memory to grow kernel"); | ||||
if ((nkpg->flags & PG_ZERO) == 0) | if ((nkpg->flags & PG_ZERO) == 0) | ||||
pmap_zero_page(nkpg); | pmap_zero_page(nkpg); | ||||
paddr = VM_PAGE_TO_PHYS(nkpg); | paddr = VM_PAGE_TO_PHYS(nkpg); | ||||
pmap_load_store(l2, paddr | L2_TABLE); | pmap_load_store(l2, paddr | L2_TABLE); | ||||
pmap_invalidate_page(kernel_pmap, kernel_vm_end); | pmap_invalidate_page(kernel_pmap, kernel_vm_end); | ||||
kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET; | kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET; | ||||
if (kernel_vm_end - 1 >= kernel_map->max_offset) { | if (kernel_vm_end - 1 >= vm_map_max(kernel_map)) { | ||||
kernel_vm_end = kernel_map->max_offset; | kernel_vm_end = vm_map_max(kernel_map); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/*************************************************** | /*************************************************** | ||||
* page management routines. | * page management routines. | ||||
▲ Show 20 Lines • Show All 3,570 Lines • Show Last 20 Lines |