From dd5d9e1d48396cbc226ff14fe557a55613c91fcb Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Fri, 15 Mar 2024 13:16:02 -0400 Subject: better buddy memory allocator --- abi/syscall.h | 20 ++---- arch/x86_64/paging.c | 6 +- boot/boot.h | 2 +- lib/buddymap.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/buddymap.h | 35 +++++++++++ lib/jove.h | 2 +- main.c | 8 +-- mem/buddymap.c | 151 --------------------------------------------- mem/buddymap.h | 21 ------- mem/memory.c | 10 +++ mem/memory.h | 12 ++-- mem/phys.c | 13 ++-- mem/zone.c | 97 +++++++++++++++++++++++++++++ mem/zone.h | 52 ++++++++++++++++ usr/syscall.c | 1 - 15 files changed, 386 insertions(+), 212 deletions(-) create mode 100644 lib/buddymap.c create mode 100644 lib/buddymap.h delete mode 100644 mem/buddymap.c delete mode 100644 mem/buddymap.h create mode 100644 mem/memory.c create mode 100644 mem/zone.c create mode 100644 mem/zone.h diff --git a/abi/syscall.h b/abi/syscall.h index 54a67b9..e336fe6 100644 --- a/abi/syscall.h +++ b/abi/syscall.h @@ -12,23 +12,18 @@ struct syscall_log { const char *message; }; -struct syscall_tid { +struct syscall_mem_takefree { syscall_t syscall; - intmax_t value; -}; - -struct syscall_mem_map { - syscall_t syscall; - uintptr_t phys; - uintptr_t virt; - intmax_t tid; + uintptr_t npages; }; enum { SYSCALL_LOG = 0, SYSCALL_TID, - SYSCALL_MEM_MAP, + + SYSCALL_MEM_TAKEFREE, + SYSCALL_COUNT }; @@ -50,9 +45,4 @@ intmax_t _syscall_tid(void) { _SYSCALL(&syscall_data); } -void __syscall_mem_map(uintptr_t phys, uintptr_t virt, intmax_t tid) -{ - -} - #endif diff --git a/arch/x86_64/paging.c b/arch/x86_64/paging.c index 29c4863..9e8a5ed 100644 --- a/arch/x86_64/paging.c +++ b/arch/x86_64/paging.c @@ -43,7 +43,7 @@ s_paging_fetch_table(union PageEntry *pt, size_t l, uintptr_t virt) bool entry_new = false; if(!entry.p) { entry_new = true; - entry.value = mem_phys_take4k(); + entry.value = mem_phys_alloc(1); entry.p = 1; entry.rw = 1; entry.us = 1; @@ -116,7 +116,7 @@ mem_pd_ensure_4k(struct PageDirectory *pd, uintptr_t virt, uint8_t flg) { union PageEntry pml1e = mem_paging_fetch4k(pd, virt); if(!pml1e.p) { - uintptr_t phys = mem_phys_take4k(); + uintptr_t phys = mem_phys_alloc(1); mem_paging_map4k(pd, phys, virt, flg); } } @@ -143,7 +143,7 @@ mem_ensure_range(uintptr_t from, uintptr_t to, bool rw, bool user) void mem_pd_new(struct PageDirectory *pd) { - physptr_t pml4p = mem_phys_take4k(); + physptr_t pml4p = mem_phys_alloc(1); union PageEntry *pml4 = (union PageEntry*)mem_phys_tolinear(pml4p); memset(pml4, 0, PAGESIZE); memcpy(&pml4[256], &pd->pml4_vaddr[256], PAGESIZE / 2); diff --git a/boot/boot.h b/boot/boot.h index d7571d8..cfdfa68 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -11,7 +11,7 @@ struct MemoryMapEntry { bool usable; }; -#define MEMORY_MAP_MAX_ENTRIES 64 +#define MEMORY_MAP_MAX_ENTRIES 128 struct MemoryMap { size_t count; struct MemoryMapEntry entries[MEMORY_MAP_MAX_ENTRIES]; diff --git a/lib/buddymap.c b/lib/buddymap.c new file mode 100644 index 0000000..6a616c9 --- /dev/null +++ b/lib/buddymap.c @@ -0,0 +1,168 @@ +#include "buddymap.h" +#include "jove.h" + +#define BLOCK_AT_LAYER(blocks, l, i) blocks[l][i / BUDDY_BLOCK_BITS] +#define BLOCK_BITMASK(i) (1ULL << (i % BUDDY_BLOCK_BITS)) + +bool +buddy_bit_test(struct BuddyMap *map, size_t l, size_t i) +{ + return (BLOCK_AT_LAYER(map->blocks, l, i) & BLOCK_BITMASK(i)) > 0; +} + +void +buddy_bit_mark(struct BuddyMap *map, size_t l, size_t i) +{ + size_t wi = i << l; + size_t bits = 1ULL << l; + for(size_t wl = 0; wl < map->orders; wl++) { + if(bits == 0) { + if(buddy_bit_test(map, wl - 1, (wi << 1) + 1)) bits = 1; + } + for(size_t bit = 0; bit < bits; bit++) { + size_t rbit = bit + wi; + if(l == 0 && !buddy_bit_test(map, 0, rbit)) map->free--; + BLOCK_AT_LAYER(map->blocks, wl, rbit) |= BLOCK_BITMASK(rbit); + } + bits >>= 1; + wi >>= 1; + } +} + +void +buddy_bit_free(struct BuddyMap *map, size_t l, size_t i) +{ + size_t wi = i << l; + size_t bits = 1ULL << l; + for(size_t wl = 0; wl < map->orders; wl++) { + if(bits == 0) bits = 1; + for(size_t bit = 0; bit < bits; bit++) { + size_t rbit = bit + wi; + if(l == 0 && buddy_bit_test(map, 0, rbit)) map->free++; + BLOCK_AT_LAYER(map->blocks, wl, rbit) &= ~BLOCK_BITMASK(rbit); + } + bits >>= 1; + wi >>= 1; + } +} + +static void +s_buddy_op_range( + struct BuddyMap *map, + size_t l, + size_t start, + size_t end, + void (*op)(struct BuddyMap*, size_t, size_t)) +{ + size_t layerw = 1ULL << l; + size_t start_off = start % layerw; + size_t end_off = end % layerw; + + size_t start_real = start + (start_off > 0 ? (layerw - start_off) : 0); + size_t end_real = end - end_off; + + if(start_real != start) s_buddy_op_range(map, l - 1, start, start_real, op); + if(end_real != end) s_buddy_op_range(map, l - 1, end_real, end, op); + + size_t start_bit = start_real >> l; + size_t end_bit = end_real >> l; + if(start_bit == end_bit || end_bit < start_bit) return; + for(size_t bit = start_bit; bit < end_bit; bit++) + op(map, l, bit); +} + +static size_t +s_buddy_layer_bestfit(struct BuddyMap *map, size_t length) +{ + if(length == 1) return 0; + size_t length_log2 = LOG2(length); + if(length_log2 > map->orders) length_log2 = map->orders - 1; + return length_log2; +} + +void +buddy_mark_range(struct BuddyMap *map, size_t start, size_t end) +{ + size_t l = s_buddy_layer_bestfit(map, end - start); + s_buddy_op_range(map, l, start, end, buddy_bit_mark); +} +void +buddy_free_range(struct BuddyMap *map, size_t start, size_t end) +{ + size_t l = s_buddy_layer_bestfit(map, end - start); + s_buddy_op_range(map, l, start, end, buddy_bit_free); +} + +static intmax_t +s_buddy_top_firstfree(struct BuddyMap *map) +{ + size_t layer = map->orders - 1; + size_t layer_bits = map->bits >> layer; + size_t layer_blocks = layer_bits / BUDDY_BLOCK_BITS; + for(size_t i = 0; i < layer_blocks; i++) { + if(map->blocks[layer][i] == (uintptr_t)-1) continue; + for(size_t j = 0; j < BUDDY_BLOCK_BITS; j++) { + size_t bit = (i * BUDDY_BLOCK_BITS) + j; + if(buddy_bit_test(map, layer, bit)) continue; + return bit; + } + } + return -1; +} + +static intmax_t +s_buddy_top_alloc_contig(struct BuddyMap *map, size_t length) +{ + size_t layer = map->orders - 1; + size_t layer_bits = map->bits >> layer; + + size_t contig_base = 0; + size_t contig_bits = 0; + for(size_t i = 0; i < layer_bits; i++) { + if(buddy_bit_test(map, layer, i)) { + contig_base = i + 1; + contig_bits = 0; + continue; + } + if(++contig_bits == length) { + return contig_base; + } + } + return -1; +} + +intmax_t +buddy_alloc(struct BuddyMap *map, size_t length) +{ + size_t layer = s_buddy_layer_bestfit(map, length); + size_t layerw = 1ULL << layer; + size_t allocw = length / layerw; + + if(allocw == 0) allocw = 1; + if(allocw > 1) + return s_buddy_top_alloc_contig(map, length); + + intmax_t alloci = s_buddy_top_firstfree(map); + if(alloci < 0) { + klogf("Top layer is full!\n"); + return -1; + } + + for(int wlayer = map->orders - 2; wlayer > layer; wlayer--) { + alloci <<= 1; + if(buddy_bit_test(map, wlayer, alloci)) { + alloci++; + } + } + alloci <<= 1; + if(buddy_bit_test(map, layer, alloci)) alloci++; + + s_buddy_op_range(map, layer, alloci, alloci + length, buddy_bit_mark); + return alloci; +} + +void +buddy_free(struct BuddyMap *map, size_t i, size_t length) +{ + buddy_free_range(map, i, i + length); +} diff --git a/lib/buddymap.h b/lib/buddymap.h new file mode 100644 index 0000000..1af8dfb --- /dev/null +++ b/lib/buddymap.h @@ -0,0 +1,35 @@ +#ifndef JOVE_LIB_BUDDYMAP_H +#define JOVE_LIB_BUDDYMAP_H 1 + +#include +#include +#include + +#define BUDDY_BLOCK_BYTES sizeof(intmax_t) +#define BUDDY_BLOCK_BITS (BUDDY_BLOCK_BYTES * 8) + +#define BUDDY_BITS_FOR(range) (range * 2) +#define BUDDY_BLOCKS_FOR(range) (BUDDY_BITS_FOR(range) / BUDDY_BLOCK_BITS) + +struct BuddyMap +{ + size_t orders; + size_t bits; + size_t free; + uintmax_t **blocks; +}; + +#define BUDDY_BIT_PARTIAL 0 +#define BUDDY_BIT_FULL 1 + +bool buddy_bit_test(struct BuddyMap *map, size_t l, size_t i); +void buddy_bit_mark(struct BuddyMap *map, size_t l, size_t i); +void buddy_bit_free(struct BuddyMap *map, size_t l, size_t i); + +void buddy_mark_range(struct BuddyMap *map, size_t start, size_t end); +void buddy_free_range(struct BuddyMap *map, size_t start, size_t end); + +intmax_t buddy_alloc(struct BuddyMap *map, size_t length); +void buddy_free(struct BuddyMap *map, size_t i, size_t length); + +#endif diff --git a/lib/jove.h b/lib/jove.h index 4aa60ed..6015112 100644 --- a/lib/jove.h +++ b/lib/jove.h @@ -4,7 +4,7 @@ #define ALWAYS_INLINE inline __attribute__((always_inline)) #define PAGEALIGN __attribute__((aligned(0x1000))) -//#define LOG2(n) (__builtin_clz(n) ^ 31) +#define LOG2(n) (31 - __builtin_clz(n)) extern void *_kernel_start; extern void *_kernel_end; diff --git a/main.c b/main.c index e74d8df..9341489 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ #include "arch/arch.h" #include "io/log.h" -#include "mem/buddymap.h" #include "mem/memory.h" +#include "mem/zone.h" #include "boot/cmdline.h" #include "tsk/tasking.h" #include "ird/initrd.h" @@ -12,11 +12,9 @@ void kernel_main(void) { serial_setup(); - arch_tables_setup(); + //arch_tables_setup(); - mem_buddy_setup(); - mem_paging_setup(); - mem_slab_setup(); + mem_setup(); cmdline_kernel_setup(); diff --git a/mem/buddymap.c b/mem/buddymap.c deleted file mode 100644 index 5165876..0000000 --- a/mem/buddymap.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "buddymap.h" -#include "lib/string.h" -#include "boot/boot.h" -#include "io/log.h" -#include - -#define ENTRY_BITS (sizeof(uintmax_t) * 8) -#define ENTRY_SIZE (ENTRY_BITS * PAGESIZE) -#define ENTRY_COUNT (MEMMAP_BUDDY_LIMIT / ENTRY_SIZE) -#define BUDDY_LAYERS 4 - -uintmax_t s_buddy_l0[ENTRY_COUNT]; -uintmax_t s_buddy_l1[ENTRY_COUNT << 1]; -uintmax_t s_buddy_l2[ENTRY_COUNT << 2]; -uintmax_t s_buddy_l3[ENTRY_COUNT << 3]; -uintmax_t *s_buddies[BUDDY_LAYERS] = { - s_buddy_l0, - s_buddy_l1, - s_buddy_l2, - s_buddy_l3 -}; -size_t s_buddies_lastfree[BUDDY_LAYERS] = { 1, 1, 1, 1 }; - -static bool -s_buddy_test(size_t l, size_t i) -{ - return (s_buddies[l][i / (ENTRY_BITS)] & (1ULL << (i % (ENTRY_BITS)))) > 0; -} - -static void -s_buddy_set(size_t l, size_t i) -{ - size_t j = i << l; - size_t w = 1 << l; - for(int layer = 0; layer < BUDDY_LAYERS; layer++) - { - if(w == 0) w = 1; - for(size_t bit = 0; bit < w; bit++) { - size_t entry = (j + bit) / ENTRY_BITS; - s_buddies[layer][entry] |= (1ULL << (j + bit % ENTRY_BITS)); - } - j >>= 1; - w >>= 1; - } -} - -static void -s_buddy_unset(size_t l, size_t i) -{ - size_t j = i << l; - size_t w = 1 << l; - bool free_upper = false; - for(int layer = 0; layer < BUDDY_LAYERS; layer++) - { - if(w == 0) { - size_t lower = (j << 1) % ENTRY_BITS; - size_t other = (lower + 1); - size_t entry = (j << 1) / ENTRY_BITS; - if((s_buddies[layer-1][entry] & (1ULL << lower)) > 0 && - (s_buddies[layer-1][entry] & (1ULL << other)) > 0) - s_buddies[layer][entry >> 1] &= ~(1ULL << (j % ENTRY_BITS)); - } - - for(size_t bit = 0; bit < w; bit++) { - size_t entry = j / ENTRY_BITS; - s_buddies[layer][entry] |= (1ULL << bit); - } - j >>= 1; - w >>= 1; - } -} - -void -mem_buddy_set_range(uintptr_t base, size_t length) -{ - for(int l = 0; l < BUDDY_LAYERS; l++) { - size_t bits = (length / PAGESIZE) >> l; - size_t biti = (base / PAGESIZE) >> l; - - if(bits == 0) bits = 1; - for(size_t i = 0; i < bits; i++) { - size_t entry = (biti + i) / ENTRY_BITS; - s_buddies[l][entry] |= 1ULL << ((biti + i) % ENTRY_BITS); - } - } -} - -void -mem_buddy_free_range(uintptr_t base, size_t length) -{ - for(int l = 0; l < BUDDY_LAYERS; l++) { - size_t bits = (length / PAGESIZE) >> l; - size_t biti = (base / PAGESIZE) >> l; - size_t bitbase = (biti * PAGESIZE) << l; - - if(bits == 0) continue; - for(size_t i = 0; i < bits; i++, bitbase += (PAGESIZE << l)) { - if(bitbase < base) continue; - size_t entry = (biti + i) / ENTRY_BITS; - s_buddies[l][entry] &= ~(1ULL << ((biti+ i) % ENTRY_BITS)); - } - } -} - - -uintptr_t -mem_buddy_takefree(size_t l) -{ - uintmax_t *layer = s_buddies[l]; - size_t lastfree = s_buddies_lastfree[l]; - if(s_buddy_test(l, lastfree)) lastfree = 0; - size_t entries = ENTRY_COUNT >> l; - for(size_t i = lastfree / ENTRY_BITS; i < entries; i++) { - uintmax_t entry = layer[i]; - if(entry == (uintmax_t)-1LL) continue; - for(size_t j = 0; j < ENTRY_BITS; j++) { - if((entry & (1ULL << j)) == 0) { - size_t bit = (i * ENTRY_BITS) + j; - s_buddies_lastfree[l] = bit + 1; - s_buddy_set(l, bit); - return bit * (PAGESIZE << l); - } - } - } - return 0; -} - -void -mem_buddy_setup() -{ - memset(s_buddy_l0, 0xFF, sizeof(s_buddy_l0)); - memset(s_buddy_l1, 0xFF, sizeof(s_buddy_l1)); - memset(s_buddy_l2, 0xFF, sizeof(s_buddy_l2)); - memset(s_buddy_l3, 0xFF, sizeof(s_buddy_l3)); - - for(int i = 0; i < boot_memorymap.count; i++) { - struct MemoryMapEntry *entry = &boot_memorymap.entries[i]; - klogf("%2i\t%#016X -> %#016X (%i)\n", - i, entry->base, entry->base + entry->length, entry->usable); - if(entry->base > MEMMAP_BUDDY_LIMIT) continue; - size_t length = entry->length; - if(entry->base + length > MEMMAP_BUDDY_LIMIT) length = MEMMAP_BUDDY_LIMIT - (entry->base + length); - if(entry->usable) - mem_buddy_free_range(entry->base, entry->length); - } - - s_buddies[0][0] |= 1; - s_buddies[1][0] |= 1; - s_buddies[2][0] |= 1; - s_buddies[3][0] |= 1; -} diff --git a/mem/buddymap.h b/mem/buddymap.h deleted file mode 100644 index 2f4f5dc..0000000 --- a/mem/buddymap.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef JOVE_MEMORY_BUDDYMAP_H -#define JOVE_MEMORY_BUDDYMAP_H 1 - -#include "memory.h" -#include -#include - -#define MEMMAP_BUDDY_LIMIT (4 * GiB) - -void mem_buddy_set_range(uintptr_t base, size_t length); -void mem_buddy_free_range(uintptr_t base, size_t length); -uintptr_t mem_buddy_takefree(size_t layer); - -#define mem_buddy_takefree_4k() mem_buddy_takefree(0) -#define mem_buddy_takefree_8k() mem_buddy_takefree(1) -#define mem_buddy_takefree_16k() mem_buddy_takefree(2) -#define mem_buddy_takefree_32k() mem_buddy_takefree(3) - -void mem_buddy_setup(void); - -#endif diff --git a/mem/memory.c b/mem/memory.c new file mode 100644 index 0000000..26bbbd8 --- /dev/null +++ b/mem/memory.c @@ -0,0 +1,10 @@ +#include "memory.h" +#include "zone.h" + +void +mem_setup(void) +{ + mem_zone_setup_standard(); + mem_paging_setup(); + mem_slab_setup(); +} diff --git a/mem/memory.h b/mem/memory.h index 3956852..41323ed 100644 --- a/mem/memory.h +++ b/mem/memory.h @@ -32,12 +32,12 @@ bool mem_check_ptr(const void *ptr); * @param user flag to mark page as user accessable*/ void mem_ensure_range(uintptr_t from, uintptr_t to, bool rw, bool user); -/**Make sure the range indicated is available in memory for specified pd +/** Make sure the range indicated is available in memory for specified pd * If necessary, allocate new pages using the passed flags * @param pd pointer to page directory to edit - * @param from start of the range. - * @param to end of the range. - * @param rw flag to mark page is writeable. + * @param from start of the range + * @param to end of the range + * @param rw flag to mark page is writeable * @param user flag to mark page as user accessable*/ void mem_ensure_range_for(void *pd, uintptr_t from, uintptr_t to, bool rw, bool user); @@ -52,7 +52,9 @@ void mem_free(void *ptr); /*Physical*/ -physptr_t mem_phys_take4k(void); +physptr_t mem_phys_alloc(size_t pages); void mem_phys_reserve(physptr_t start, size_t len); +void mem_setup(void); + #endif diff --git a/mem/phys.c b/mem/phys.c index e56a4d6..00f3531 100644 --- a/mem/phys.c +++ b/mem/phys.c @@ -1,14 +1,9 @@ #include "memory.h" -#include "buddymap.h" +#include "zone.h" physptr_t -mem_phys_take4k(void) +mem_phys_alloc(size_t pages) { - return mem_buddy_takefree_4k(); -} - -void -mem_phys_reserve(physptr_t start, size_t len) -{ - mem_buddy_set_range(start, len); + physptr_t ptr = mem_zone_alloc(MEM_ZONE_STANDARD, pages); + return ptr; } diff --git a/mem/zone.c b/mem/zone.c new file mode 100644 index 0000000..489383a --- /dev/null +++ b/mem/zone.c @@ -0,0 +1,97 @@ +#include "zone.h" +#include "memory.h" +#include "boot/boot.h" +#include "lib/string.h" +#include "io/log.h" + +#define MEM_ZONE_STANDARD_PAGES (MEM_ZONE_STANDARD_LIMIT >> 12) + +static uintmax_t + s_zone_standard_freemap_blocks_flat[BUDDY_BLOCKS_FOR(MEM_ZONE_STANDARD_PAGES)]; +static uintmax_t* + s_zone_standard_freemap_blocks[MEM_BUDDY_ORDERS]; + +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, + .free = 0, + .blocks = s_zone_standard_freemap_blocks + } + }, + { + .name = "Higher", + .base = MEM_ZONE_HIGHER_BASE, + .limit = -1, + .freemap = { + .orders = MEM_BUDDY_ORDERS + } + } +}; + +void +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; + + buddy_mark_range(&s_zones[zone].freemap, base >> 12, limit >> 12); +} + +void +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); +} + +uintptr_t +mem_zone_alloc(size_t zone, size_t pages) +{ + struct PhysicalMemoryZone *pmz = &s_zones[zone]; + intmax_t pagei = buddy_alloc(&pmz->freemap, pages); + if(pagei < 0) return 0; + + return (((uintmax_t)pagei) << 12) + pmz->base; +} + +void +mem_zone_setup_standard(void) +{ + struct PhysicalMemoryZone *standard_zone = &s_zones[MEM_ZONE_STANDARD]; + uintmax_t *map_block_layer_base = s_zone_standard_freemap_blocks_flat; + for(size_t i = 0; i < MEM_BUDDY_ORDERS; i++) { + size_t layer_entries = (standard_zone->freemap.bits / BUDDY_BLOCK_BITS) >> i; + standard_zone->freemap.blocks[i] = map_block_layer_base; + memset(map_block_layer_base, 0xFF, layer_entries * sizeof(uintmax_t)); + map_block_layer_base = &map_block_layer_base[layer_entries]; + } + + for(int i = 0; i < boot_memorymap.count; i++) { + struct MemoryMapEntry *entry = &boot_memorymap.entries[i]; + klogf("%2i\t%#016X -> %#016X (%i)\n", + i, entry->base, entry->base + entry->length, entry->usable); + if(entry->base > MEM_ZONE_STANDARD_LIMIT) continue; + size_t limit = entry->base + entry->length; + if(limit > MEM_ZONE_STANDARD_LIMIT) limit = MEM_ZONE_STANDARD_LIMIT; + if(entry->usable) + mem_zone_free(MEM_ZONE_STANDARD, entry->base, limit); + } +} diff --git a/mem/zone.h b/mem/zone.h new file mode 100644 index 0000000..7e863bf --- /dev/null +++ b/mem/zone.h @@ -0,0 +1,52 @@ +#ifndef JOVE_MEM_ZONE_H +#define JOVE_MEM_ZONE_H 1 + +#include +#include "lib/buddymap.h" + +enum { + MEM_ZONE_STANDARD = 0, /* First GiB of physical memory. */ + MEM_ZONE_HIGHER, + MEM_ZONE_COUNT +}; + +#define MEM_ZONE_STANDARD_BASE 0 +#define MEM_ZONE_STANDARD_LIMIT (1 * GiB) +#define MEM_ZONE_HIGHER_BASE MEM_ZONE_STANDARD_LIMIT + +#define MEM_BUDDY_ORDERS 12 +struct PhysicalMemoryZone +{ + const char *name; + + uintptr_t base; + uintptr_t limit; + + size_t npages_total; + size_t npages_free; + + struct BuddyMap freemap; +}; + +/** Using a given zone, reserve a range of physical addresses + * @param zone identifier of zone to modify + * @param base starting address to reserve + * @param limit ending address to reserve*/ +void mem_zone_resv(size_t zone, uintptr_t base, uintptr_t limit); + +/** Using a given zone, free a range of physical addresses + * @param zone identifier of zone to modify + * @param base starting address to free + * @param limit ending address to free*/ +void mem_zone_free(size_t zone, uintptr_t base, uintptr_t limit); + +/** Allocate a number of pages from the given zone + * @param zone identifier of the zone to modify + * @param pages number of pages to allocate + * @return physical memory address of allocation + * zero if allocation failed*/ +uintptr_t mem_zone_alloc(size_t zone, size_t pages); + +void mem_zone_setup_standard(void); + +#endif diff --git a/usr/syscall.c b/usr/syscall.c index 834bd5b..8680845 100644 --- a/usr/syscall.c +++ b/usr/syscall.c @@ -5,7 +5,6 @@ int _syscall_handler_log(struct syscall_log *req) { - klogf("Message ptr %#016X\n", req->message); if(!mem_check_ptr(req->message)) return -1; klogf("%s", req->message); return 0; -- cgit v1.2.1