* grow the number of kernel page table entries, if needed */
| 1292 | * grow the number of kernel page table entries, if needed |
| 1293 | */ |
| 1294 | void |
| 1295 | pmap_growkernel(vm_offset_t addr) |
| 1296 | { |
| 1297 | vm_page_t nkpg; |
| 1298 | pd_entry_t *pde, *pdpe; |
| 1299 | pt_entry_t *pte; |
| 1300 | int i, req_class; |
| 1301 | |
| 1302 | mtx_assert(&kernel_map->system_mtx, MA_OWNED); |
| 1303 | req_class = VM_ALLOC_INTERRUPT; |
| 1304 | addr = roundup2(addr, NBSEG); |
| 1305 | if (addr - 1 >= vm_map_max(kernel_map)) |
| 1306 | addr = vm_map_max(kernel_map); |
| 1307 | while (kernel_vm_end < addr) { |
| 1308 | pdpe = pmap_segmap(kernel_pmap, kernel_vm_end); |
| 1309 | #ifdef __mips_n64 |
| 1310 | if (*pdpe == 0) { |
| 1311 | /* new intermediate page table entry */ |
| 1312 | nkpg = pmap_alloc_direct_page(nkpt, req_class); |
| 1313 | if (nkpg == NULL) |
| 1314 | panic("pmap_growkernel: no memory to grow kernel"); |
| 1315 | *pdpe = (pd_entry_t)MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(nkpg)); |
| 1316 | continue; /* try again */ |
| 1317 | } |
| 1318 | #endif |
| 1319 | pde = pmap_pdpe_to_pde(pdpe, kernel_vm_end); |
| 1320 | if (*pde != 0) { |
| 1321 | kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK; |
| 1322 | if (kernel_vm_end - 1 >= vm_map_max(kernel_map)) { |
| 1323 | kernel_vm_end = vm_map_max(kernel_map); |
| 1324 | break; |
| 1325 | } |
| 1326 | continue; |
| 1327 | } |
| 1328 | |
| 1329 | /* |
| 1330 | * This index is bogus, but out of the way |
| 1331 | */ |
| 1332 | nkpg = pmap_alloc_direct_page(nkpt, req_class); |
| 1333 | #ifndef __mips_n64 |
| 1334 | if (nkpg == NULL && vm_page_reclaim_contig(req_class, 1, |
| 1335 | 0, MIPS_KSEG0_LARGEST_PHYS, PAGE_SIZE, 0)) |
| 1336 | nkpg = pmap_alloc_direct_page(nkpt, req_class); |
| 1337 | #endif |
| 1338 | if (nkpg == NULL) |
| 1339 | panic("pmap_growkernel: no memory to grow kernel"); |
| 1340 | nkpt++; |
| 1341 | *pde = (pd_entry_t)MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(nkpg)); |
| 1342 | |
| 1343 | /* |
| 1344 | * The R[4-7]?00 stores only one copy of the Global bit in |
| 1345 | * the translation lookaside buffer for each 2 page entry. |
| 1346 | * Thus invalid entrys must have the Global bit set so when |
| 1347 | * Entry LO and Entry HI G bits are anded together they will |
| 1348 | * produce a global bit to store in the tlb. |
| 1349 | */ |
| 1350 | pte = (pt_entry_t *)*pde; |
| 1351 | for (i = 0; i < NPTEPG; i++) |
no test coverage detected