Nucleus
Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
diff --git a/memory/region.c b/memory/region.c
index 26cbc37..469f6b4 100644
--- a/memory/region.c
+++ b/memory/region.c
@@ -17,6 +17,7 @@ static void vm_copy(Object *, Object *);
static void region_new(Object *);
static void region_delete(Object *);
static void region_copy(Object *, Object *);
+static int region_compare(void *, void *);
/* Virtual Memory Namespace object type */
ObjectType virtualMemoryType = {
@@ -40,7 +41,17 @@ static void
vm_new(Object *obj)
{
VirtualMemory *vm = (void *) obj;
- vm->regions = create_list(&vmRegionType, LIST_NORMAL);
+ vm->regions = create_list(&vmRegionType, LIST_ORDERED, region_compare);
+
+ /* Create stack region */
+ VMRegion *stack = new(&vmRegionType);
+ stack->start = 0xDFC00000;
+ stack->end = 0xE0000000;
+ stack->prot = PROT_READ | PROT_WRITE;
+ stack->flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ vm->stack = stack;
+
+ asm volatile("mov %%cr3, %0" : "=r" (vm->pageDir));
}
/* Destroy a Virtual Memory object */
@@ -49,6 +60,8 @@ vm_delete(Object *obj)
{
VirtualMemory *vm = (void *) obj;
destroy_list(vm->regions);
+ if (vm->stack)
+ put(vm->stack);
}
/* Copy a Virtual Memory object */
@@ -62,6 +75,9 @@ vm_copy(Object *a, Object *b)
add(child->regions, insert);
put(insert);
}
+ if (parent->stack)
+ child->stack = copy(parent->stack);
+ child->pageDir = clone_dir();
}
/* Delete a Virtual Memory Region */
@@ -105,6 +121,14 @@ region_copy(Object *a, Object *b)
child->back = get(parent->back);
}
+/* Compare two regions of memory */
+static int
+region_compare(void *a, void *b)
+{
+ VMRegion *ra = a, *rb = b;
+ return rb->start - ra->start;
+}
+
/* Remove a range of pages from a region's page cache */
static void
remove_cache_range(VMRegion *region, uintptr_t start, uintptr_t end)
@@ -130,6 +154,18 @@ remove_cache_range(VMRegion *region, uintptr_t start, uintptr_t end)
}
}
+/* Switch to another virtual memory namespace */
+void
+switch_to_mm(VirtualMemory *vm)
+{
+ if (!current || !current->vm)
+ return;
+ if (!vm->pageDir)
+ return;
+ if (current->vm->pageDir != vm->pageDir)
+ switch_dir(vm->pageDir);
+}
+
/* Find a Virtual Memory Region by address */
VMRegion *
find_region(uintptr_t addr)
@@ -140,7 +176,7 @@ find_region(uintptr_t addr)
return region;
}
- region = current->stack;
+ region = current->vm->stack;
if (region->start <= addr && region->end > addr)
return region;
@@ -203,14 +239,3 @@ vm_create_region(void *addr, size_t len, int prot, int flags, off_t offset,
add(current->vm->regions, region);
return region;
}
-
-/* Create a Virtual Memory Region for the stack */
-VMRegion *
-vm_create_stack(void)
-{
- VMRegion *stack = vm_create_region((void *) 0xDFC00000, 0x400000,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, NULL);
- remove(current->vm->regions, stack);
- return stack;
-}