Author: bonefish Date: 2010-05-27 13:50:40 +0200 (Thu, 27 May 2010) New Revision: 36947 Changeset: http://dev.haiku-os.org/changeset/36947/haiku Modified: haiku/trunk/headers/private/kernel/boot/addr_range.h haiku/trunk/headers/private/kernel/boot/kernel_args.h haiku/trunk/src/system/boot/loader/kernel_args.cpp haiku/trunk/src/system/boot/platform/bios_ia32/mmu.cpp haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp Log: * Introduced phys_addr_range type, an equivalent to addr_range for physical address ranges, and a set of support functions working with it. * Changed the type of the kernel_args physical address range arrays to phys_addr_range and adjusted the code working with those. * Removed a bunch of duplicated address range code in the PPC's mmu.cpp. Modified: haiku/trunk/headers/private/kernel/boot/addr_range.h =================================================================== --- haiku/trunk/headers/private/kernel/boot/addr_range.h 2010-05-27 11:37:46 UTC (rev 36946) +++ haiku/trunk/headers/private/kernel/boot/addr_range.h 2010-05-27 11:50:40 UTC (rev 36947) @@ -1,4 +1,5 @@ /* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx * Copyright 2004-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved. * Distributed under the terms of the MIT License. */ @@ -11,27 +12,42 @@ typedef struct addr_range { addr_t start; - addr_t size; + size_t size; } addr_range; +typedef struct phys_addr_range { + phys_addr_t start; + phys_size_t size; +} phys_addr_range; + + #ifdef __cplusplus extern "C" { #endif -status_t insert_address_range(addr_range *ranges, uint32 *_numRanges, - uint32 maxRanges, addr_t start, uint32 size); -status_t remove_address_range(addr_range *ranges, uint32 *_numRanges, - uint32 maxRanges, addr_t start, uint32 size); -bool get_free_address_range(addr_range *ranges, uint32 numRanges, addr_t base, - size_t size, addr_t *_rangeBase); -bool is_address_range_covered(addr_range *ranges, uint32 numRanges, addr_t base, +status_t insert_address_range(addr_range* ranges, uint32* _numRanges, + uint32 maxRanges, addr_t start, size_t size); +status_t remove_address_range(addr_range* ranges, uint32* _numRanges, + uint32 maxRanges, addr_t start, size_t size); +bool get_free_address_range(addr_range* ranges, uint32 numRanges, addr_t base, + size_t size, addr_t* _rangeBase); +bool is_address_range_covered(addr_range* ranges, uint32 numRanges, addr_t base, size_t size); -status_t insert_physical_memory_range(addr_t start, uint32 size); -status_t insert_physical_allocated_range(addr_t start, uint32 size); -status_t insert_virtual_allocated_range(addr_t start, uint32 size); +status_t insert_physical_address_range(phys_addr_range* ranges, + uint32* _numRanges, uint32 maxRanges, phys_addr_t start, phys_size_t size); +status_t remove_physical_address_range(phys_addr_range* ranges, + uint32* _numRanges, uint32 maxRanges, phys_addr_t start, phys_size_t size); +bool get_free_physical_address_range(phys_addr_range* ranges, uint32 numRanges, + phys_addr_t base, phys_size_t size, phys_addr_t* _rangeBase); +bool is_physical_address_range_covered(phys_addr_range* ranges, + uint32 numRanges, phys_addr_t base, phys_size_t size); +status_t insert_physical_memory_range(phys_addr_t start, phys_size_t size); +status_t insert_physical_allocated_range(phys_addr_t start, phys_size_t size); +status_t insert_virtual_allocated_range(addr_t start, size_t size); + #ifdef __cplusplus } #endif Modified: haiku/trunk/headers/private/kernel/boot/kernel_args.h =================================================================== --- haiku/trunk/headers/private/kernel/boot/kernel_args.h 2010-05-27 11:37:46 UTC (rev 36946) +++ haiku/trunk/headers/private/kernel/boot/kernel_args.h 2010-05-27 11:50:40 UTC (rev 36947) @@ -46,14 +46,14 @@ struct preloaded_image kernel_image; struct preloaded_image *preloaded_images; - uint32 num_physical_memory_ranges; - addr_range physical_memory_range[MAX_PHYSICAL_MEMORY_RANGE]; - uint32 num_physical_allocated_ranges; - addr_range physical_allocated_range[MAX_PHYSICAL_ALLOCATED_RANGE]; - uint32 num_virtual_allocated_ranges; - addr_range virtual_allocated_range[MAX_VIRTUAL_ALLOCATED_RANGE]; - uint32 num_kernel_args_ranges; - addr_range kernel_args_range[MAX_KERNEL_ARGS_RANGE]; + uint32 num_physical_memory_ranges; + phys_addr_range physical_memory_range[MAX_PHYSICAL_MEMORY_RANGE]; + uint32 num_physical_allocated_ranges; + phys_addr_range physical_allocated_range[MAX_PHYSICAL_ALLOCATED_RANGE]; + uint32 num_virtual_allocated_ranges; + addr_range virtual_allocated_range[MAX_VIRTUAL_ALLOCATED_RANGE]; + uint32 num_kernel_args_ranges; + addr_range kernel_args_range[MAX_KERNEL_ARGS_RANGE]; uint32 num_cpus; addr_range cpu_kstack[MAX_BOOT_CPUS]; @@ -63,7 +63,7 @@ struct driver_settings_file *driver_settings; struct { - addr_range physical_buffer; + phys_addr_range physical_buffer; uint32 bytes_per_row; uint16 width; uint16 height; Modified: haiku/trunk/src/system/boot/loader/kernel_args.cpp =================================================================== --- haiku/trunk/src/system/boot/loader/kernel_args.cpp 2010-05-27 11:37:46 UTC (rev 36946) +++ haiku/trunk/src/system/boot/loader/kernel_args.cpp 2010-05-27 11:50:40 UTC (rev 36947) @@ -1,4 +1,5 @@ /* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@xxxxxxx * Copyright 2004-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * Distributed under the terms of the MIT License. */ @@ -24,8 +25,9 @@ static size_t sFree = kChunkSize; +template<typename RangeType> static void -remove_range_index(addr_range* ranges, uint32& numRanges, uint32 index) +remove_range_index(RangeType* ranges, uint32& numRanges, uint32 index) { if (index + 1 == numRanges) { // remove last range @@ -34,43 +36,25 @@ } memmove(&ranges[index], &ranges[index + 1], - sizeof(addr_range) * (numRanges - 1 - index)); + sizeof(RangeType) * (numRanges - 1 - index)); numRanges--; } +template<typename RangeType, typename AddressType, typename SizeType> static status_t -add_kernel_args_range(void* start, uint32 size) +insert_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, + AddressType start, SizeType size) { - return insert_address_range(gKernelArgs.kernel_args_range, - &gKernelArgs.num_kernel_args_ranges, MAX_KERNEL_ARGS_RANGE, - (addr_t)start, size); -} - - -// #pragma mark - addr_range utility - - -/*! Inserts the specified (start, size) pair (aka range) in the - addr_range array. - It will extend existing ranges in order to have as little - ranges in the array as possible. - Returns B_OK on success, or B_ENTRY_NOT_FOUND if there was - no free array entry available anymore. -*/ -extern "C" status_t -insert_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, - addr_t start, uint32 size) -{ uint32 numRanges = *_numRanges; start = ROUNDDOWN(start, B_PAGE_SIZE); size = ROUNDUP(size, B_PAGE_SIZE); - addr_t end = start + size; + AddressType end = start + size; for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; + AddressType rangeStart = ranges[i].start; + AddressType rangeEnd = rangeStart + ranges[i].size; if (end < rangeStart || start > rangeEnd) { // ranges don't intersect or touch each other @@ -99,8 +83,8 @@ rangeStart = ranges[i].start; rangeEnd = rangeStart + ranges[i].size; - addr_t joinStart = ranges[j].start; - addr_t joinEnd = joinStart + ranges[j].size; + AddressType joinStart = ranges[j].start; + AddressType joinEnd = joinStart + ranges[j].size; if (rangeStart <= joinEnd && joinEnd <= rangeEnd) { // join range that used to be before the current one, or @@ -128,7 +112,7 @@ if (numRanges >= maxRanges) return B_ENTRY_NOT_FOUND; - ranges[numRanges].start = (addr_t)start; + ranges[numRanges].start = (AddressType)start; ranges[numRanges].size = size; (*_numRanges)++; @@ -136,18 +120,19 @@ } -extern "C" status_t -remove_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, - addr_t start, uint32 size) +template<typename RangeType, typename AddressType, typename SizeType> +static status_t +remove_range(RangeType* ranges, uint32* _numRanges, uint32 maxRanges, + AddressType start, SizeType size) { uint32 numRanges = *_numRanges; - addr_t end = ROUNDUP(start + size, B_PAGE_SIZE); + AddressType end = ROUNDUP(start + size, B_PAGE_SIZE); start = ROUNDDOWN(start, B_PAGE_SIZE); for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; + AddressType rangeStart = ranges[i].start; + AddressType rangeEnd = rangeStart + ranges[i].size; if (start <= rangeStart) { if (end <= rangeStart) { @@ -172,8 +157,8 @@ // the range. We keep the head of the range and insert its tail // as a new range. ranges[i].size = start - rangeStart; - return insert_address_range(ranges, _numRanges, maxRanges, - end, rangeEnd - end); + return insert_range<RangeType, AddressType, SizeType>(ranges, + _numRanges, maxRanges, end, rangeEnd - end); } } @@ -182,11 +167,12 @@ } -bool -get_free_address_range(addr_range *ranges, uint32 numRanges, addr_t base, - size_t size, addr_t *_rangeBase) +template<typename RangeType, typename AddressType, typename SizeType> +static bool +get_free_range(RangeType* ranges, uint32 numRanges, AddressType base, + SizeType size, AddressType* _rangeBase) { - addr_t end = base + size - 1; + AddressType end = base + size - 1; if (end < base) return false; @@ -195,8 +181,8 @@ // intersects with an existing one. for (uint32 i = 0; i < numRanges;) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = ranges[i].start + ranges[i].size - 1; + AddressType rangeStart = ranges[i].start; + AddressType rangeEnd = ranges[i].start + ranges[i].size - 1; if (base <= rangeEnd && rangeStart <= end) { base = rangeEnd + 1; @@ -216,20 +202,21 @@ } -bool -is_address_range_covered(addr_range* ranges, uint32 numRanges, addr_t base, - size_t size) +template<typename RangeType, typename AddressType, typename SizeType> +static bool +is_range_covered(RangeType* ranges, uint32 numRanges, AddressType base, + SizeType size) { // Note: We don't assume that the ranges are sorted, so we can't do this // in a simple loop. Instead we restart the loop whenever the start of the // given range intersects with an existing one. for (uint32 i = 0; i < numRanges;) { - addr_t rangeStart = ranges[i].start; - addr_t rangeSize = ranges[i].size; + AddressType rangeStart = ranges[i].start; + AddressType rangeSize = ranges[i].size; if (rangeStart <= base && rangeSize > base - rangeStart) { - size_t intersect = std::min(rangeStart + rangeSize - base, size); + SizeType intersect = std::min(rangeStart + rangeSize - base, size); base += intersect; size -= intersect; if (size == 0) @@ -246,26 +233,126 @@ } +// #pragma mark - + + +static status_t +add_kernel_args_range(void* start, size_t size) +{ + return insert_address_range(gKernelArgs.kernel_args_range, + &gKernelArgs.num_kernel_args_ranges, MAX_KERNEL_ARGS_RANGE, + (addr_t)start, size); +} + + +// #pragma mark - addr_range utility functions + + +/*! Inserts the specified (start, size) pair (aka range) in the + addr_range array. + It will extend existing ranges in order to have as little + ranges in the array as possible. + Returns B_OK on success, or B_ENTRY_NOT_FOUND if there was + no free array entry available anymore. +*/ +extern "C" status_t +insert_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, + addr_t start, size_t size) +{ + return insert_range<addr_range, addr_t, size_t>(ranges, _numRanges, + maxRanges, start, size); +} + + +extern "C" status_t +remove_address_range(addr_range* ranges, uint32* _numRanges, uint32 maxRanges, + addr_t start, size_t size) +{ + return remove_range<addr_range, addr_t, size_t>(ranges, _numRanges, + maxRanges, start, size); +} + + +bool +get_free_address_range(addr_range* ranges, uint32 numRanges, addr_t base, + size_t size, addr_t* _rangeBase) +{ + return get_free_range<addr_range, addr_t, size_t>(ranges, numRanges, base, + size, _rangeBase); +} + + +bool +is_address_range_covered(addr_range* ranges, uint32 numRanges, addr_t base, + size_t size) +{ + return is_range_covered<addr_range, addr_t, size_t>(ranges, numRanges, base, + size); +} + + +// #pragma mark - phys_addr_range utility functions + + status_t -insert_physical_memory_range(addr_t start, uint32 size) +insert_physical_address_range(phys_addr_range* ranges, uint32* _numRanges, + uint32 maxRanges, phys_addr_t start, phys_size_t size) { - return insert_address_range(gKernelArgs.physical_memory_range, + return insert_range<phys_addr_range, phys_addr_t, phys_size_t>(ranges, + _numRanges, maxRanges, start, size); +} + + +status_t +remove_physical_address_range(phys_addr_range* ranges, uint32* _numRanges, + uint32 maxRanges, phys_addr_t start, phys_size_t size) +{ + return remove_range<phys_addr_range, phys_addr_t, phys_size_t>(ranges, + _numRanges, maxRanges, start, size); +} + + +bool +get_free_physical_address_range(phys_addr_range* ranges, uint32 numRanges, + phys_addr_t base, phys_size_t size, phys_addr_t* _rangeBase) +{ + return get_free_range<phys_addr_range, phys_addr_t, phys_size_t>(ranges, + numRanges, base, size, _rangeBase); +} + + +bool +is_physical_address_range_covered(phys_addr_range* ranges, uint32 numRanges, + phys_addr_t base, phys_size_t size) +{ + return is_range_covered<phys_addr_range, phys_addr_t, phys_size_t>(ranges, + numRanges, base, size); +} + + +// #pragma mark - kernel args range functions + + +status_t +insert_physical_memory_range(addr_t start, size_t size) +{ + return insert_physical_address_range(gKernelArgs.physical_memory_range, &gKernelArgs.num_physical_memory_ranges, MAX_PHYSICAL_MEMORY_RANGE, start, size); } status_t -insert_physical_allocated_range(addr_t start, uint32 size) +insert_physical_allocated_range(addr_t start, size_t size) { - return insert_address_range(gKernelArgs.physical_allocated_range, + return insert_physical_address_range(gKernelArgs.physical_allocated_range, &gKernelArgs.num_physical_allocated_ranges, MAX_PHYSICAL_ALLOCATED_RANGE, start, size); } status_t -insert_virtual_allocated_range(addr_t start, uint32 size) +insert_virtual_allocated_range(addr_t start, size_t size) { return insert_address_range(gKernelArgs.virtual_allocated_range, &gKernelArgs.num_virtual_allocated_ranges, MAX_VIRTUAL_ALLOCATED_RANGE, @@ -273,7 +360,7 @@ } -// #pragma mark - kernel_args allocations +// #pragma mark - kernel_args allocations /*! This function can be used to allocate memory that is going @@ -329,15 +416,15 @@ /*! Convenience function that copies strdup() functions for the kernel args heap. */ -extern "C" char * -kernel_args_strdup(const char *string) +extern "C" char* +kernel_args_strdup(const char* string) { if (string == NULL || string[0] == '\0') return NULL; size_t length = strlen(string) + 1; - char *target = (char *)kernel_args_malloc(length); + char* target = (char*)kernel_args_malloc(length); if (target == NULL) return NULL; @@ -351,7 +438,7 @@ enough for its current usage in the boot loader, though. */ extern "C" void -kernel_args_free(void *block) +kernel_args_free(void* block) { if (sLast != block) { // sorry, we're dumb Modified: haiku/trunk/src/system/boot/platform/bios_ia32/mmu.cpp =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/mmu.cpp 2010-05-27 11:37:46 UTC (rev 36946) +++ haiku/trunk/src/system/boot/platform/bios_ia32/mmu.cpp 2010-05-27 11:50:40 UTC (rev 36947) @@ -112,7 +112,7 @@ get_next_physical_address(size_t size) { addr_t base; - if (!get_free_address_range(gKernelArgs.physical_allocated_range, + if (!get_free_physical_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, sNextPhysicalAddress, size, &base)) { panic("Out of physical memory!"); @@ -258,10 +258,11 @@ } +template<typename RangeType> static void -sort_addr_range(addr_range *range, int count) +sort_addr_range(RangeType *range, int count) { - addr_range tempRange; + RangeType tempRange; bool done; int i; @@ -270,9 +271,9 @@ for (i = 1; i < count; i++) { if (range[i].start < range[i - 1].start) { done = false; - memcpy(&tempRange, &range[i], sizeof(addr_range)); - memcpy(&range[i], &range[i - 1], sizeof(addr_range)); - memcpy(&range[i - 1], &tempRange, sizeof(addr_range)); + memcpy(&tempRange, &range[i], sizeof(RangeType)); + memcpy(&range[i], &range[i - 1], sizeof(RangeType)); + memcpy(&range[i - 1], &tempRange, sizeof(RangeType)); } } } while (!done); @@ -451,14 +452,14 @@ mmu_allocate_physical(addr_t base, size_t size) { // check whether the physical memory range exists at all - if (!is_address_range_covered(gKernelArgs.physical_memory_range, + if (!is_physical_address_range_covered(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges, base, size)) { return false; } // check whether the physical range is still free addr_t foundBase; - if (!get_free_address_range(gKernelArgs.physical_allocated_range, + if (!get_free_physical_address_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges, sNextPhysicalAddress, size, &foundBase) || foundBase != base) { return false; @@ -717,7 +718,7 @@ size_t size = gKernelArgs.physical_memory_range[i].size; if (size < 64 * 1024) { addr_t start = gKernelArgs.physical_memory_range[i].start; - remove_address_range(gKernelArgs.physical_memory_range, + remove_physical_address_range(gKernelArgs.physical_memory_range, &gKernelArgs.num_physical_memory_ranges, MAX_PHYSICAL_MEMORY_RANGE, start, size); } Modified: haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp =================================================================== --- haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp 2010-05-27 11:37:46 UTC (rev 36946) +++ haiku/trunk/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp 2010-05-27 11:50:40 UTC (rev 36947) @@ -5,6 +5,8 @@ #include <platform_arch.h> +#include <boot/addr_range.h> +#include <boot/kernel_args.h> #include <boot/platform.h> #include <boot/stage2.h> #include <boot/stdio.h> @@ -38,167 +40,6 @@ extern "C" uint8 _end; -static void -remove_range_index(addr_range *ranges, uint32 &numRanges, uint32 index) -{ - if (index + 1 == numRanges) { - // remove last range - numRanges--; - return; - } - - memmove(&ranges[index], &ranges[index + 1], - sizeof(addr_range) * (numRanges - 1 - index)); - numRanges--; -} - - -static status_t -insert_memory_range(addr_range *ranges, uint32 &numRanges, uint32 maxRanges, - const void *_start, uint32 _size) -{ - addr_t start = ROUNDDOWN(addr_t(_start), B_PAGE_SIZE); - addr_t end = ROUNDUP(addr_t(_start) + _size, B_PAGE_SIZE); - addr_t size = end - start; - if (size == 0) - return B_OK; - - for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; - - if (end < rangeStart || start > rangeEnd) { - // ranges don't intersect or touch each other - continue; - } - if (start >= rangeStart && end <= rangeEnd) { - // range is already completely covered - return B_OK; - } - - if (start < rangeStart) { - // prepend to the existing range - ranges[i].start = start; - ranges[i].size += rangeStart - start; - } - if (end > ranges[i].start + ranges[i].size) { - // append to the existing range - ranges[i].size = end - ranges[i].start; - } - - // join ranges if possible - - for (uint32 j = 0; j < numRanges; j++) { - if (i == j) - continue; - - rangeStart = ranges[i].start; - rangeEnd = rangeStart + ranges[i].size; - addr_t joinStart = ranges[j].start; - addr_t joinEnd = joinStart + ranges[j].size; - - if (rangeStart <= joinEnd && joinEnd <= rangeEnd) { - // join range that used to be before the current one, or - // the one that's now entirely included by the current one - if (joinStart < rangeStart) { - ranges[i].size += rangeStart - joinStart; - ranges[i].start = joinStart; - } - - remove_range_index(ranges, numRanges, j--); - } else if (joinStart <= rangeEnd && joinEnd > rangeEnd) { - // join range that used to be after the current one - ranges[i].size += joinEnd - rangeEnd; - - remove_range_index(ranges, numRanges, j--); - } - } - return B_OK; - } - - // no range matched, we need to create a new one - - if (numRanges >= maxRanges) - return B_ENTRY_NOT_FOUND; - - ranges[numRanges].start = (addr_t)start; - ranges[numRanges].size = size; - numRanges++; - - return B_OK; -} - - -static status_t -remove_memory_range(addr_range *ranges, uint32 &numRanges, uint32 maxRanges, - const void *_start, uint32 _size) -{ - addr_t start = ROUNDDOWN(addr_t(_start), B_PAGE_SIZE); - addr_t end = ROUNDUP(addr_t(_start) + _size, B_PAGE_SIZE); - - for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; - - if (start <= rangeStart) { - if (end <= rangeStart) { - // no intersection - } else if (end >= rangeEnd) { - // remove the complete range - remove_range_index(ranges, numRanges, i); - i--; - } else { - // remove the head of the range - ranges[i].start = end; - ranges[i].size = rangeEnd - end; - } - } else if (end >= rangeEnd) { - if (start < rangeEnd) { - // remove the tail - ranges[i].size = start - rangeStart; - } // else: no intersection - } else { - // rangeStart < start < end < rangeEnd - // The ugly case: We have to remove something from the middle of - // the range. We keep the head of the range and insert its tail - // as a new range. - ranges[i].size = start - rangeStart; - return insert_memory_range(ranges, numRanges, maxRanges, - (void*)end, rangeEnd - end); - } - } - - return B_OK; -} - - -static status_t -insert_physical_memory_range(void *start, uint32 size) -{ - return insert_memory_range(gKernelArgs.physical_memory_range, - gKernelArgs.num_physical_memory_ranges, MAX_PHYSICAL_MEMORY_RANGE, - start, size); -} - - -static status_t -insert_physical_allocated_range(void *start, uint32 size) -{ - return insert_memory_range(gKernelArgs.physical_allocated_range, - gKernelArgs.num_physical_allocated_ranges, MAX_PHYSICAL_ALLOCATED_RANGE, - start, size); -} - - -static status_t -insert_virtual_allocated_range(void *start, uint32 size) -{ - return insert_memory_range(gKernelArgs.virtual_allocated_range, - gKernelArgs.num_virtual_allocated_ranges, MAX_VIRTUAL_ALLOCATED_RANGE, - start, size); -} - - #if 0 static status_t insert_virtual_range_to_keep(void *start, uint32 size) @@ -213,9 +54,9 @@ static status_t remove_virtual_range_to_keep(void *start, uint32 size) { - return remove_memory_range(gKernelArgs.arch_args.virtual_ranges_to_keep, - gKernelArgs.arch_args.num_virtual_ranges_to_keep, - MAX_VIRTUAL_RANGES_TO_KEEP, start, size); + return remove_address_range(gKernelArgs.arch_args.virtual_ranges_to_keep, + &gKernelArgs.arch_args.num_virtual_ranges_to_keep, + MAX_VIRTUAL_RANGES_TO_KEEP, (addr_t)start, size); } @@ -249,8 +90,8 @@ total += regions[i].size; - if (insert_physical_memory_range(regions[i].base, regions[i].size) - != B_OK) { + if (insert_physical_memory_range((addr_t)regions[i].base, + regions[i].size) != B_OK) { printf("cannot map physical memory range (num ranges = %lu)!\n", gKernelArgs.num_physical_memory_ranges); return B_ERROR; @@ -262,76 +103,40 @@ static bool -is_in_range(addr_range *ranges, uint32 numRanges, void *address, size_t size) -{ - // Note: This function returns whether any single allocated range - // completely contains the given range. If the given range crosses - // allocated range boundaries, but is nevertheless covered completely, the - // function returns false. But since the range management code joins - // touching ranges, this should never happen. - addr_t start = (addr_t)address; - addr_t end = start + size; - - for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; - - if ((start >= rangeStart && start < rangeEnd) - || (end >= rangeStart && end < rangeEnd)) - return true; - } - return false; -} - - -static bool -intersects_ranges(addr_range *ranges, uint32 numRanges, void *address, - size_t size) -{ - addr_t start = (addr_t)address; - addr_t end = start + size; - - for (uint32 i = 0; i < numRanges; i++) { - addr_t rangeStart = ranges[i].start; - addr_t rangeEnd = rangeStart + ranges[i].size; - - if ((start >= rangeStart && start < rangeEnd) - || (rangeStart >= start && rangeStart < end)) { - return true; - } - } - return false; -} - - -static bool is_virtual_allocated(void *address, size_t size) { - return intersects_ranges(gKernelArgs.virtual_allocated_range, - gKernelArgs.num_virtual_allocated_ranges, address, size); + addr_t foundBase; + return !get_free_address_range(gKernelArgs.virtual_allocated_range, + gKernelArgs.num_virtual_allocated_ranges, (addr_t)address, size, + &foundBase) + || foundBase != (addr_t)address; } static bool is_physical_allocated(void *address, size_t size) { - return intersects_ranges(gKernelArgs.physical_allocated_range, - gKernelArgs.num_physical_allocated_ranges, address, size); + phys_addr_t foundBase; + return !get_free_physical_address_range( + gKernelArgs.physical_allocated_range, + gKernelArgs.num_physical_allocated_ranges, (addr_t)address, size, + &foundBase) + || foundBase != (addr_t)address; } static bool is_physical_memory(void *address, size_t size) { - return is_in_range(gKernelArgs.physical_memory_range, - gKernelArgs.num_physical_memory_ranges, address, size); + return is_physical_address_range_covered(gKernelArgs.physical_memory_range, + gKernelArgs.num_physical_memory_ranges, (addr_t)address, size); } static bool is_physical_memory(void *address) { - return is_physical_memory(address, 0); + return is_physical_memory(address, 1); } @@ -453,7 +258,7 @@ // insert range in physical allocated, if it points to physical memory if (is_physical_memory(map->physical_address) - && insert_physical_allocated_range(map->physical_address, + && insert_physical_allocated_range((addr_t)map->physical_address, map->length) != B_OK) { printf("cannot map physical allocated range (num ranges = %lu)!\n", gKernelArgs.num_physical_allocated_ranges); @@ -479,7 +284,7 @@ // insert range in virtual allocated - if (insert_virtual_allocated_range(map->virtual_address, + if (insert_virtual_allocated_range((addr_t)map->virtual_address, map->length) != B_OK) { printf("cannot map virtual allocated range (num ranges = %lu)!\n", gKernelArgs.num_virtual_allocated_ranges); @@ -656,8 +461,8 @@ printf("mmu_alloc: va %p, pa %p, size %u\n", virtualAddress, physicalAddress, size); - insert_virtual_allocated_range(virtualAddress, size); - insert_physical_allocated_range(physicalAddress, size); + insert_virtual_allocated_range((addr_t)virtualAddress, size); + insert_physical_allocated_range((addr_t)physicalAddress, size); map_range(virtualAddress, physicalAddress, size, protection); @@ -706,14 +511,16 @@ // insert range in physical allocated if needed if (is_physical_memory(physicalAddress) - && insert_physical_allocated_range(physicalAddress, length) != B_OK) { + && insert_physical_allocated_range((addr_t)physicalAddress, length) + != B_OK) { error = -1; return OF_FAILED; } // insert range in virtual allocated - if (insert_virtual_allocated_range(virtualAddress, length) != B_OK) { + if (insert_virtual_allocated_range((addr_t)virtualAddress, length) + != B_OK) { error = -2; return OF_FAILED; } @@ -976,16 +783,16 @@ //map_range((void *)realBase, (void *)realBase, realSize * 2, PAGE_READ_WRITE); //map_range((void *)(total - realSize), (void *)(total - realSize), realSize, PAGE_READ_WRITE); //map_range((void *)table, (void *)table, tableSize, PAGE_READ_WRITE); - insert_physical_allocated_range((void *)realBase, realSize * 2); - insert_virtual_allocated_range((void *)realBase, realSize * 2); - insert_physical_allocated_range((void *)(total - realSize), realSize); - insert_virtual_allocated_range((void *)(total - realSize), realSize); - insert_physical_allocated_range((void *)table, tableSize); - insert_virtual_allocated_range((void *)table, tableSize); + insert_physical_allocated_range(realBase, realSize * 2); + insert_virtual_allocated_range(realBase, realSize * 2); + insert_physical_allocated_range(total - realSize, realSize); + insert_virtual_allocated_range(total - realSize, realSize); + insert_physical_allocated_range((addr_t)table, tableSize); + insert_virtual_allocated_range((addr_t)table, tableSize); // QEMU OpenHackware work-around - insert_physical_allocated_range((void *)0x05800000, 0x06000000 - 0x05800000); - insert_virtual_allocated_range((void *)0x05800000, 0x06000000 - 0x05800000); + insert_physical_allocated_range(0x05800000, 0x06000000 - 0x05800000); + insert_virtual_allocated_range(0x05800000, 0x06000000 - 0x05800000); physicalTable = table; }