summaryrefslogtreecommitdiff
path: root/kernel/memory/physalloc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--kernel/memory/physalloc.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 8971bcf..7551c75 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -1,11 +1,14 @@
#include <lib.h>
#include <comus/memory.h>
#include <comus/asm.h>
+#include <comus/mboot.h>
+#include <stdint.h>
#include "physalloc.h"
extern char kernel_start[];
extern char kernel_end[];
+static void *kernel_real_end = NULL;
// between memory_start and kernel_start will be the bitmap
static uintptr_t memory_start = 0;
@@ -26,19 +29,20 @@ static const char *segment_type_str[] = {
static int n_pages(const struct memory_segment *m)
{
- return m->len / PAGE_SIZE;
+ return (m->len + PAGE_SIZE - 1) / PAGE_SIZE;
}
-static void *page_at(int i)
+static void *page_at(size_t i)
{
- int cur_page = 0;
+ size_t cur_page = 0;
+ const struct memory_segment *m = page_start;
for (uint64_t idx = 0; idx < segment_count; idx++) {
- const struct memory_segment *m = page_start;
- int pages = n_pages(m);
+ size_t pages = n_pages(m);
if (i - cur_page < pages) {
return (void *)(m->addr + (PAGE_SIZE * (i - cur_page)));
}
cur_page += pages;
+ m++;
}
return NULL;
}
@@ -47,8 +51,8 @@ static long page_idx(void *page)
{
uintptr_t addr = (uintptr_t)page;
int cur_page = 0;
+ const struct memory_segment *m = page_start;
for (uint64_t idx = 0; idx < segment_count; idx++) {
- const struct memory_segment *m = page_start;
if (addr < m->addr) {
return -1;
}
@@ -56,13 +60,14 @@ static long page_idx(void *page)
return cur_page + ((addr - m->addr) / PAGE_SIZE);
}
cur_page += n_pages(m);
+ m++;
}
return -1;
}
static inline bool bitmap_get(size_t i)
{
- return (bitmap[i / 64] >> i % 64) & 1;
+ return (bitmap[i / 64] >> (i % 64)) & 1;
}
static inline void bitmap_set(size_t i, bool v)
@@ -71,9 +76,9 @@ static inline void bitmap_set(size_t i, bool v)
free_memory -= PAGE_SIZE;
else
free_memory += PAGE_SIZE;
- int idx = i / 64;
- bitmap[idx] &= ~(1 << i % 64);
- bitmap[idx] |= (v << i % 64);
+ size_t idx = i / 64;
+ bitmap[idx] &= ~(1 << (i % 64));
+ bitmap[idx] |= (v << (i % 64));
}
void *alloc_phys_page(void)
@@ -105,9 +110,17 @@ void *alloc_phys_pages_exact(size_t pages)
free_region_start = i;
n_contiguous++;
if (n_contiguous == pages) {
+ void *pADDR;
+ pADDR = page_at(free_region_start);
+
+ if (pADDR == NULL) {
+ n_contiguous = 0;
+ continue;
+ }
+
for (size_t j = 0; j < pages; j++)
bitmap_set(free_region_start + j, true);
- return page_at(free_region_start);
+ return pADDR;
}
} else
n_contiguous = 0;
@@ -118,6 +131,7 @@ void *alloc_phys_pages_exact(size_t pages)
struct phys_page_slice alloc_phys_page_withextra(size_t max_pages)
{
+ panic("please dont use this its broken i think?!\n");
if (max_pages == 0)
return PHYS_PAGE_SLICE_NULL;
@@ -160,6 +174,7 @@ void free_phys_page(void *ptr)
void free_phys_pages_slice(struct phys_page_slice slice)
{
+ panic("please dont use this its broken i think?!\n");
free_phys_pages(slice.pagestart, slice.num_pages);
}
@@ -200,7 +215,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment)
if (memory_start)
start = memory_start;
else
- start = (uintptr_t)kernel_end;
+ start = (uintptr_t)kernel_real_end;
if (segment->addr < start) {
addr = start;
@@ -232,6 +247,10 @@ void physalloc_init(struct memory_map *map)
segment_count = 0;
+ kernel_real_end = mboot_end();
+ if ((char *)kernel_real_end < kernel_end)
+ kernel_real_end = kernel_end;
+
for (uint32_t i = 0; i < map->entry_count; i++) {
struct memory_segment *segment = &map->entries[i];
@@ -245,7 +264,7 @@ void physalloc_init(struct memory_map *map)
long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1;
long bitmap_size = bitmap_pages * PAGE_SIZE;
- bitmap = (uint64_t *)page_align((uintptr_t)kernel_end);
+ bitmap = (uint64_t *)page_align((uintptr_t)kernel_real_end);
long page_area_size = segment_count * sizeof(struct memory_segment);
char *page_area_addr = (char *)bitmap + bitmap_size;