haiku/headers/private/kernel/boot/addr_range.h
Michael Lotz d750211a65 bootloader: Split memory map handling into add/remove passes.
The memory map may be unordered and include overlapping ranges. To make
sure that nothing gets included as usable that should actually be
excluded, first scan for all usable ranges and add them, then remove
anything unusable from these ranges again.

To calculate the amount of unusable memory, count the total after the
first pass and then subtract the total after the second. This way, only
unusable ranges that actually overlap physical memory (and therefore
reduce the amount of usable memory) get excluded.

Note that the explicit ignore of the ACPI reclaim memory is subsumed by
the above. We still don't want to add this region to the usable memory
map, as that would allow the kernel to allocate pages into that region,
possibly corrupting ACPI tables before they were used. We also don't
want to add it as an allocated range, as it is not guaranteed that ACPI
is done with the tables before the unused bootloader ranges are freed in
the kernel.

Also add the missing unusable memory amount from ignoring the first MiB
of memory in the EFI loader.

May fix #16056 although it is not certain that graphics memory ranges
are actually included in the memory map.

Change-Id: Ie7991d2c4dcd988edac2995b3a7efc509fa0f4a3
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2814
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
2020-05-26 04:04:35 +00:00

47 lines
1.4 KiB
C

/*
* Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_BOOT_ADDR_RANGE_H
#define KERNEL_BOOT_ADDR_RANGE_H
#include <SupportDefs.h>
typedef struct addr_range {
uint64 start;
uint64 size;
} _PACKED addr_range;
#ifdef __cplusplus
extern "C" {
#endif
status_t insert_address_range(addr_range* ranges, uint32* _numRanges,
uint32 maxRanges, uint64 start, uint64 size);
status_t remove_address_range(addr_range* ranges, uint32* _numRanges,
uint32 maxRanges, uint64 start, uint64 size);
bool get_free_address_range(addr_range* ranges, uint32 numRanges, uint64 base,
uint64 size, uint64* _rangeBase);
bool is_address_range_covered(addr_range* ranges, uint32 numRanges, uint64 base,
uint64 size);
uint64 total_address_ranges_size(addr_range* ranges, uint32 numRanges);
void sort_address_ranges(addr_range* ranges, uint32 numRanges);
status_t insert_physical_memory_range(uint64 start, uint64 size);
status_t remove_physical_memory_range(uint64 start, uint64 size);
uint64 total_physical_memory();
status_t insert_physical_allocated_range(uint64 start, uint64 size);
status_t insert_virtual_allocated_range(uint64 start, uint64 size);
void ignore_physical_memory_ranges_beyond_4gb();
#ifdef __cplusplus
}
#endif
#endif /* KERNEL_BOOT_ADDR_RANGE_H */