summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2016-09-03 15:18:46 +0200
committerRichard Braun <rbraun@sceen.net>2016-09-03 16:59:04 +0200
commitf6a2436d282a06e5f34789c8c5917e838fa26643 (patch)
treed04e9761ce58b7236567671bc2757ed78f319a39 /vm
parent094cfe430457e15d34098af6a04e7f9af950d414 (diff)
Fix early physical page allocation
Import upstream biosmem and vm_page changes, and adjust for local modifications. Specifically, the biosmem module was mistakenly loading physical segments that did not clip with the heap as completely available. This change makes it load them as completely unavailable during startup, and once the VM system is ready, additional pages are loaded. * i386/i386at/biosmem.c (DEBUG): New macro. (struct biosmem_segment): Remove members `avail_start' and `avail_end'. (biosmem_heap_cur): Remove variable. (biosmem_heap_bottom, biosmem_heap_top, biosmem_heap_topdown): New variables. (biosmem_find_boot_data_update, biosmem_find_boot_data): Remove functions. (biosmem_find_heap_clip, biosmem_find_heap): New functions. (biosmem_setup_allocator): Rewritten to use the new biosmem_find_heap function. (biosmem_bootalloc): Support both bottom-up and top-down allocations. (biosmem_directmap_size): Renamed to ... (biosmem_directmap_end): ... this function. (biosmem_load_segment): Fix segment loading. (biosmem_setup): Restrict usable memory to the directmap segment. (biosmem_free_usable_range): Add checks on input parameters. (biosmem_free_usable_update_start, biosmem_free_usable_start, biosmem_free_usable_reserved, biosmem_free_usable_end): Remove functions. (biosmem_free_usable_entry): Rewritten to use the new biosmem_find_heap function. (biosmem_free_usable): Restrict usable memory to the directmap segment. * i386/i386at/biosmem.h (biosmem_bootalloc): Update description. (biosmem_directmap_size): Renamed to ... (biosmem_directmap_end): ... this function. (biosmem_free_usable): Update declaration. * i386/i386at/model_dep.c (machine_init): Call biosmem_free_usable. * vm/vm_page.c (DEBUG): New macro. (struct vm_page_seg): New member `heap_present'. (vm_page_load): Remove heap related parameters. (vm_page_load_heap): New function. * vm/vm_page.h (vm_page_load): Remove heap related parameters. Update description. (vm_page_load_heap): New function.
Diffstat (limited to 'vm')
-rw-r--r--vm/vm_page.c45
-rw-r--r--vm/vm_page.h15
2 files changed, 47 insertions, 13 deletions
diff --git a/vm/vm_page.c b/vm/vm_page.c
index a868fce8..12e6a5ea 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -43,6 +43,8 @@
#include <sys/types.h>
#include <vm/vm_page.h>
+#define DEBUG 0
+
#define __init
#define __initdata
#define __read_mostly
@@ -123,6 +125,7 @@ struct vm_page_seg {
struct vm_page_boot_seg {
phys_addr_t start;
phys_addr_t end;
+ boolean_t heap_present;
phys_addr_t avail_start;
phys_addr_t avail_end;
};
@@ -483,29 +486,55 @@ vm_page_seg_free(struct vm_page_seg *seg, struct vm_page *page,
}
void __init
-vm_page_load(unsigned int seg_index, phys_addr_t start, phys_addr_t end,
- phys_addr_t avail_start, phys_addr_t avail_end)
+vm_page_load(unsigned int seg_index, phys_addr_t start, phys_addr_t end)
{
struct vm_page_boot_seg *seg;
assert(seg_index < ARRAY_SIZE(vm_page_boot_segs));
assert(vm_page_aligned(start));
assert(vm_page_aligned(end));
- assert(vm_page_aligned(avail_start));
- assert(vm_page_aligned(avail_end));
assert(start < end);
- assert(start <= avail_start);
- assert(avail_end <= end);
assert(vm_page_segs_size < ARRAY_SIZE(vm_page_boot_segs));
seg = &vm_page_boot_segs[seg_index];
seg->start = start;
seg->end = end;
- seg->avail_start = avail_start;
- seg->avail_end = avail_end;
+ seg->heap_present = FALSE;
+
+#if DEBUG
+ printf("vm_page: load: %s: %llx:%llx\n",
+ vm_page_seg_name(seg_index),
+ (unsigned long long)start, (unsigned long long)end);
+#endif
+
vm_page_segs_size++;
}
+void
+vm_page_load_heap(unsigned int seg_index, phys_addr_t start, phys_addr_t end)
+{
+ struct vm_page_boot_seg *seg;
+
+ assert(seg_index < ARRAY_SIZE(vm_page_boot_segs));
+ assert(vm_page_aligned(start));
+ assert(vm_page_aligned(end));
+
+ seg = &vm_page_boot_segs[seg_index];
+
+ assert(seg->start <= start);
+ assert(end <= seg-> end);
+
+ seg->avail_start = start;
+ seg->avail_end = end;
+ seg->heap_present = TRUE;
+
+#if DEBUG
+ printf("vm_page: heap: %s: %llx:%llx\n",
+ vm_page_seg_name(seg_index),
+ (unsigned long long)start, (unsigned long long)end);
+#endif
+}
+
int
vm_page_ready(void)
{
diff --git a/vm/vm_page.h b/vm/vm_page.h
index f2e20a78..dc5d5c3a 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -442,13 +442,18 @@ vm_page_get_priv(const struct vm_page *page)
/*
* Load physical memory into the vm_page module at boot time.
*
- * The avail_start and avail_end parameters are used to maintain a simple
- * heap for bootstrap allocations.
- *
* All addresses must be page-aligned. Segments can be loaded in any order.
*/
-void vm_page_load(unsigned int seg_index, phys_addr_t start, phys_addr_t end,
- phys_addr_t avail_start, phys_addr_t avail_end);
+void vm_page_load(unsigned int seg_index, phys_addr_t start, phys_addr_t end);
+
+/*
+ * Load available physical memory into the vm_page module at boot time.
+ *
+ * The segment referred to must have been loaded with vm_page_load
+ * before loading its heap.
+ */
+void vm_page_load_heap(unsigned int seg_index, phys_addr_t start,
+ phys_addr_t end);
/*
* Return true if the vm_page module is completely initialized, false