summaryrefslogtreecommitdiffstats
path: root/mem/zone.c
diff options
context:
space:
mode:
Diffstat (limited to 'mem/zone.c')
-rw-r--r--mem/zone.c93
1 files changed, 71 insertions, 22 deletions
diff --git a/mem/zone.c b/mem/zone.c
index 489383a..42a056e 100644
--- a/mem/zone.c
+++ b/mem/zone.c
@@ -2,9 +2,11 @@
#include "memory.h"
#include "boot/boot.h"
#include "lib/string.h"
+#include "lib/jove.h"
+#include "sys/errno.h"
#include "io/log.h"
-#define MEM_ZONE_STANDARD_PAGES (MEM_ZONE_STANDARD_LIMIT >> 12)
+#define MEM_ZONE_STANDARD_PAGES (MEM_ZONE_STANDARD_LIMIT >> PAGE_SHIFT)
static uintmax_t
s_zone_standard_freemap_blocks_flat[BUDDY_BLOCKS_FOR(MEM_ZONE_STANDARD_PAGES)];
@@ -17,8 +19,6 @@ static struct PhysicalMemoryZone s_zones[MEM_ZONE_COUNT] =
.name = "Standard",
.base = MEM_ZONE_STANDARD_BASE,
.limit = MEM_ZONE_STANDARD_LIMIT,
- .npages_total = MEM_ZONE_STANDARD_PAGES,
- .npages_free = 0,
.freemap = {
.orders = MEM_BUDDY_ORDERS,
.bits = MEM_ZONE_STANDARD_PAGES,
@@ -36,40 +36,89 @@ static struct PhysicalMemoryZone s_zones[MEM_ZONE_COUNT] =
}
};
+int
+mem_zone_for(uintptr_t addr)
+{
+ addr &= ~PAGE_MASK;
+ for(size_t zonei = 0; zonei < MEM_ZONE_COUNT; zonei++)
+ {
+ struct PhysicalMemoryZone *pmz = &s_zones[zonei];
+ if(addr >= pmz->base && addr < pmz->limit) return zonei;
+ }
+ return -ENOTFOUND;
+}
+
+uintptr_t
+mem_zone_bound_lower(size_t zone)
+{
+ if(zone >= MEM_ZONE_COUNT) return 0;
+ return s_zones[zone].base;
+}
+
+uintptr_t
+mem_zone_bound_upper(size_t zone)
+{
+ if(zone >= MEM_ZONE_COUNT) return 0;
+ return s_zones[zone].limit;
+}
+
+size_t
+mem_zone_pages_free(size_t zone)
+{
+ if(zone >= MEM_ZONE_COUNT) return 0;
+ return s_zones[zone].freemap.free;
+}
+
void
+_zone_resv(struct PhysicalMemoryZone *zone, uintptr_t base, uintptr_t limit)
+{
+ buddy_mark_range(&zone->freemap, base >> PAGE_SHIFT, limit >> PAGE_SHIFT);
+}
+
+void
+_zone_free(struct PhysicalMemoryZone *zone, uintptr_t base, uintptr_t limit)
+{
+ buddy_free_range(&zone->freemap, base >> PAGE_SHIFT, limit >> PAGE_SHIFT);
+}
+
+int
mem_zone_resv(size_t zone, uintptr_t base, uintptr_t limit)
{
- size_t base_off = base % PAGESIZE;
- size_t limit_off = limit % PAGESIZE;
-
- if(base_off > 0) base += (PAGESIZE - base_off);
- limit -= limit_off;
+ if(zone >= MEM_ZONE_COUNT) return -EINVAL;
- buddy_mark_range(&s_zones[zone].freemap, base >> 12, limit >> 12);
+ size_t base_off = base % PAGE_SIZE;
+
+ size_t base_real = (base & ~PAGE_MASK) + (base_off > 0 ? PAGE_SIZE : 0);
+ size_t limit_real = limit & ~PAGE_MASK;
+ _zone_resv(&s_zones[zone], base_real, limit_real);
+ return 0;
}
-void
+int
mem_zone_free(size_t zone, uintptr_t base, uintptr_t limit)
{
- size_t base_off = base % PAGESIZE;
- size_t limit_off = limit % PAGESIZE;
-
- if(base_off > 0) base += (PAGESIZE - base_off);
- limit -= limit_off;
-
- size_t npages = (limit - base) >> 12;
- s_zones[zone].npages_free += npages;
- buddy_free_range(&s_zones[zone].freemap, base >> 12, limit >> 12);
+ if(zone >= MEM_ZONE_COUNT) return -EINVAL;
+
+ size_t base_off = base % PAGE_SIZE;
+
+ size_t base_real = (base & ~PAGE_MASK) + (base_off > 0 ? PAGE_SIZE : 0);
+ size_t limit_real = limit & ~PAGE_MASK;
+ _zone_free(&s_zones[zone], base_real, limit_real);
+ return 0;
}
uintptr_t
mem_zone_alloc(size_t zone, size_t pages)
-{
+{
+ if(zone >= MEM_ZONE_COUNT) return 0;
+
struct PhysicalMemoryZone *pmz = &s_zones[zone];
intmax_t pagei = buddy_alloc(&pmz->freemap, pages);
- if(pagei < 0) return 0;
+ if(pagei < 0) {
+ return 0;
+ }
- return (((uintmax_t)pagei) << 12) + pmz->base;
+ return (((uintmax_t)pagei) << PAGE_SHIFT) + pmz->base;
}
void