* Allocates the virtual and physical memory required by the reservation * management system's data structures, in particular, the reservation array. */
| 1428 | * management system's data structures, in particular, the reservation array. |
| 1429 | */ |
| 1430 | vm_paddr_t |
| 1431 | vm_reserv_startup(vm_offset_t *vaddr, vm_paddr_t end) |
| 1432 | { |
| 1433 | vm_paddr_t new_end; |
| 1434 | vm_pindex_t count; |
| 1435 | size_t size; |
| 1436 | int i; |
| 1437 | |
| 1438 | count = 0; |
| 1439 | for (i = 0; i < vm_phys_nsegs; i++) { |
| 1440 | #ifdef VM_PHYSSEG_SPARSE |
| 1441 | count += howmany(vm_phys_segs[i].end, VM_LEVEL_0_SIZE) - |
| 1442 | vm_phys_segs[i].start / VM_LEVEL_0_SIZE; |
| 1443 | #else |
| 1444 | count = MAX(count, |
| 1445 | howmany(vm_phys_segs[i].end, VM_LEVEL_0_SIZE)); |
| 1446 | #endif |
| 1447 | } |
| 1448 | |
| 1449 | for (i = 0; phys_avail[i + 1] != 0; i += 2) { |
| 1450 | #ifdef VM_PHYSSEG_SPARSE |
| 1451 | count += howmany(phys_avail[i + 1], VM_LEVEL_0_SIZE) - |
| 1452 | phys_avail[i] / VM_LEVEL_0_SIZE; |
| 1453 | #else |
| 1454 | count = MAX(count, |
| 1455 | howmany(phys_avail[i + 1], VM_LEVEL_0_SIZE)); |
| 1456 | #endif |
| 1457 | } |
| 1458 | |
| 1459 | /* |
| 1460 | * Calculate the size (in bytes) of the reservation array. Rounding up |
| 1461 | * for partial superpages at boundaries, as every small page is mapped |
| 1462 | * to an element in the reservation array based on its physical address. |
| 1463 | * Thus, the number of elements in the reservation array can be greater |
| 1464 | * than the number of superpages. |
| 1465 | */ |
| 1466 | size = count * sizeof(struct vm_reserv); |
| 1467 | |
| 1468 | /* |
| 1469 | * Allocate and map the physical memory for the reservation array. The |
| 1470 | * next available virtual address is returned by reference. |
| 1471 | */ |
| 1472 | new_end = end - round_page(size); |
| 1473 | vm_reserv_array = (void *)(uintptr_t)pmap_map(vaddr, new_end, end, |
| 1474 | VM_PROT_READ | VM_PROT_WRITE); |
| 1475 | bzero(vm_reserv_array, size); |
| 1476 | |
| 1477 | /* |
| 1478 | * Return the next available physical address. |
| 1479 | */ |
| 1480 | return (new_end); |
| 1481 | } |
| 1482 | |
| 1483 | /* |
| 1484 | * Returns the superpage containing the given page. |
no test coverage detected