kernel/vm: Clean up virtual addr_range processing and rounding.
Only functional change should be the addition of alignment checks in allocate_early_virtual.
This commit is contained in:
+36
-34
@@ -4200,11 +4200,9 @@ create_preloaded_image_areas(struct preloaded_image* _image)
|
|||||||
void
|
void
|
||||||
vm_free_kernel_args(kernel_args* args)
|
vm_free_kernel_args(kernel_args* args)
|
||||||
{
|
{
|
||||||
uint32 i;
|
|
||||||
|
|
||||||
TRACE(("vm_free_kernel_args()\n"));
|
TRACE(("vm_free_kernel_args()\n"));
|
||||||
|
|
||||||
for (i = 0; i < args->num_kernel_args_ranges; i++) {
|
for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) {
|
||||||
area_id area = area_for((void*)(addr_t)args->kernel_args_range[i].start);
|
area_id area = area_for((void*)(addr_t)args->kernel_args_range[i].start);
|
||||||
if (area >= B_OK)
|
if (area >= B_OK)
|
||||||
delete_area(area);
|
delete_area(area);
|
||||||
@@ -4218,11 +4216,11 @@ allocate_kernel_args(kernel_args* args)
|
|||||||
TRACE(("allocate_kernel_args()\n"));
|
TRACE(("allocate_kernel_args()\n"));
|
||||||
|
|
||||||
for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) {
|
for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) {
|
||||||
void* address = (void*)(addr_t)args->kernel_args_range[i].start;
|
const addr_range& range = args->virtual_allocated_range[i];
|
||||||
|
void* address = (void*)(addr_t)range.start;
|
||||||
|
|
||||||
create_area("_kernel args_", &address, B_EXACT_ADDRESS,
|
create_area("_kernel args_", &address, B_EXACT_ADDRESS,
|
||||||
args->kernel_args_range[i].size, B_ALREADY_WIRED,
|
range.size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4233,9 +4231,9 @@ unreserve_boot_loader_ranges(kernel_args* args)
|
|||||||
TRACE(("unreserve_boot_loader_ranges()\n"));
|
TRACE(("unreserve_boot_loader_ranges()\n"));
|
||||||
|
|
||||||
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
|
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
|
||||||
|
const addr_range& range = args->virtual_allocated_range[i];
|
||||||
vm_unreserve_address_range(VMAddressSpace::KernelID(),
|
vm_unreserve_address_range(VMAddressSpace::KernelID(),
|
||||||
(void*)(addr_t)args->virtual_allocated_range[i].start,
|
(void*)(addr_t)range.start, range.size);
|
||||||
args->virtual_allocated_range[i].size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4246,18 +4244,19 @@ reserve_boot_loader_ranges(kernel_args* args)
|
|||||||
TRACE(("reserve_boot_loader_ranges()\n"));
|
TRACE(("reserve_boot_loader_ranges()\n"));
|
||||||
|
|
||||||
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
|
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
|
||||||
void* address = (void*)(addr_t)args->virtual_allocated_range[i].start;
|
const addr_range& range = args->virtual_allocated_range[i];
|
||||||
|
void* address = (void*)(addr_t)range.start;
|
||||||
|
|
||||||
// If the address is no kernel address, we just skip it. The
|
// If the address is no kernel address, we just skip it. The
|
||||||
// architecture specific code has to deal with it.
|
// architecture specific code has to deal with it.
|
||||||
if (!IS_KERNEL_ADDRESS(address)) {
|
if (!IS_KERNEL_ADDRESS(address)) {
|
||||||
dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %"
|
dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %"
|
||||||
B_PRIu64 "\n", address, args->virtual_allocated_range[i].size);
|
B_PRIu64 "\n", address, range.size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t status = vm_reserve_address_range(VMAddressSpace::KernelID(),
|
status_t status = vm_reserve_address_range(VMAddressSpace::KernelID(),
|
||||||
&address, B_EXACT_ADDRESS, args->virtual_allocated_range[i].size, 0);
|
&address, B_EXACT_ADDRESS, range.size, 0);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
panic("could not reserve boot loader ranges\n");
|
panic("could not reserve boot loader ranges\n");
|
||||||
}
|
}
|
||||||
@@ -4268,48 +4267,51 @@ static addr_t
|
|||||||
allocate_early_virtual(kernel_args* args, size_t size, addr_t alignment)
|
allocate_early_virtual(kernel_args* args, size_t size, addr_t alignment)
|
||||||
{
|
{
|
||||||
size = PAGE_ALIGN(size);
|
size = PAGE_ALIGN(size);
|
||||||
|
if (alignment <= B_PAGE_SIZE) {
|
||||||
|
// All allocations are naturally page-aligned.
|
||||||
|
alignment = 0;
|
||||||
|
} else {
|
||||||
|
ASSERT((alignment % B_PAGE_SIZE) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// find a slot in the virtual allocation addr range
|
// Find a slot in the virtual allocation ranges.
|
||||||
for (uint32 i = 1; i < args->num_virtual_allocated_ranges; i++) {
|
for (uint32 i = 1; i < args->num_virtual_allocated_ranges; i++) {
|
||||||
// check to see if the space between this one and the last is big enough
|
// Check if the space between this one and the previous is big enough.
|
||||||
addr_t rangeStart = args->virtual_allocated_range[i].start;
|
const addr_range& range = args->virtual_allocated_range[i];
|
||||||
addr_t previousRangeEnd = args->virtual_allocated_range[i - 1].start
|
addr_range& previousRange = args->virtual_allocated_range[i - 1];
|
||||||
+ args->virtual_allocated_range[i - 1].size;
|
const addr_t previousRangeEnd = previousRange.start + previousRange.size;
|
||||||
|
|
||||||
addr_t base = alignment > 0
|
addr_t base = alignment > 0
|
||||||
? ROUNDUP(previousRangeEnd, alignment) : previousRangeEnd;
|
? ROUNDUP(previousRangeEnd, alignment) : previousRangeEnd;
|
||||||
|
|
||||||
if (base >= KERNEL_BASE && base < rangeStart
|
if (base >= KERNEL_BASE && base < range.start && (range.start - base) >= size) {
|
||||||
&& rangeStart - base >= size) {
|
previousRange.size += base + size - previousRangeEnd;
|
||||||
args->virtual_allocated_range[i - 1].size
|
|
||||||
+= base + size - previousRangeEnd;
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we hadn't found one between allocation ranges. this is ok.
|
// We didn't find one between allocation ranges. This is OK.
|
||||||
// see if there's a gap after the last one
|
// See if there's a gap after the last one.
|
||||||
int lastEntryIndex = args->num_virtual_allocated_ranges - 1;
|
addr_range& lastRange
|
||||||
addr_t lastRangeEnd = args->virtual_allocated_range[lastEntryIndex].start
|
= args->virtual_allocated_range[args->num_virtual_allocated_ranges - 1];
|
||||||
+ args->virtual_allocated_range[lastEntryIndex].size;
|
const addr_t lastRangeEnd = lastRange.start + lastRange.size;
|
||||||
addr_t base = alignment > 0
|
addr_t base = alignment > 0
|
||||||
? ROUNDUP(lastRangeEnd, alignment) : lastRangeEnd;
|
? ROUNDUP(lastRangeEnd, alignment) : lastRangeEnd;
|
||||||
if (KERNEL_BASE + (KERNEL_SIZE - 1) - base >= size) {
|
if (KERNEL_BASE + (KERNEL_SIZE - 1) - base >= size) {
|
||||||
args->virtual_allocated_range[lastEntryIndex].size
|
lastRange.size += base + size - lastRangeEnd;
|
||||||
+= base + size - lastRangeEnd;
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if there's a gap before the first one
|
// See if there's a gap before the first one.
|
||||||
addr_t rangeStart = args->virtual_allocated_range[0].start;
|
addr_range& firstRange = args->virtual_allocated_range[0];
|
||||||
if (rangeStart > KERNEL_BASE && rangeStart - KERNEL_BASE >= size) {
|
if (firstRange.start > KERNEL_BASE && (firstRange.start - KERNEL_BASE) >= size) {
|
||||||
base = rangeStart - size;
|
base = firstRange.start - size;
|
||||||
if (alignment > 0)
|
if (alignment > 0)
|
||||||
base = ROUNDDOWN(base, alignment);
|
base = ROUNDDOWN(base, alignment);
|
||||||
|
|
||||||
if (base >= KERNEL_BASE) {
|
if (base >= KERNEL_BASE) {
|
||||||
args->virtual_allocated_range[0].start = base;
|
firstRange.start = base;
|
||||||
args->virtual_allocated_range[0].size += rangeStart - base;
|
firstRange.size += firstRange.start - base;
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4431,7 +4433,7 @@ vm_allocate_early(kernel_args* args, size_t virtualSize, size_t physicalSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map the pages
|
// map the pages
|
||||||
for (uint32 i = 0; i < PAGE_ALIGN(physicalSize) / B_PAGE_SIZE; i++) {
|
for (uint32 i = 0; i < HOWMANY(physicalSize, B_PAGE_SIZE); i++) {
|
||||||
page_num_t physicalAddress = vm_allocate_early_physical_page(args);
|
page_num_t physicalAddress = vm_allocate_early_physical_page(args);
|
||||||
if (physicalAddress == 0)
|
if (physicalAddress == 0)
|
||||||
panic("error allocating early page!\n");
|
panic("error allocating early page!\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user